0

I am trying to write and read float array(pretty large actually, 640*480) in android devices with java codes. like this one

    DataOutputStream out = ...;
for (int i=0; i<floatarray.length; ++i)
    out.writeFloat(floatarray[i]);

is very slow and I have try it in this.

WRITE:

            float[] test=new float[3];
        test[0]=1.0f;
        test[1]=1.2f;
        test[2]=1.5f;
        //long timeBeforeWrite = System.nanoTime();
        try {
            BufferedOutputStream  dataOut = new BufferedOutputStream (
                    new FileOutputStream("/sdcard/DCIM/Camera/Dual/demo.bin"));

            byte buf[]=new byte[4*test.length];

            long timeBeforeWrite = System.nanoTime();

            for (int i=0; i<test.length; ++i)
            {
                int val = Float.floatToRawIntBits(test[i]);
                buf[4 * i] = (byte) (val >> 24);
                buf[4 * i + 1] = (byte) (val >> 16) ;
                buf[4 * i + 2] = (byte) (val >> 8);
                buf[4 * i + 3] = (byte) (val);
            }



            dataOut.write(buf);

            long ct_write = System.nanoTime();
            long offset_write = ct_write - timeBeforeWrite;
            float mOffsetInMs_write = (float)(offset_write)/1000000;
            Log.e("ETA", "write float[]  " + Float.toString(mOffsetInMs_write));

            dataOut.flush();
            dataOut.close();
        } catch (IOException ex) {
            System.err.println(ex.getMessage());
        }

READ:

            float[] read=new float[3];

        try{
            BufferedInputStream  dataIn=new BufferedInputStream (new FileInputStream("/sdcard/DCIM/Camera/Dual/demo.txt"));
            byte buf[]=new byte[4*read.length];
            long timeBeforeWrite = System.nanoTime();

            dataIn.read(buf);

            for (int i=0; i<read.length; ++i)
            {
                    int val;
val = buf[4 * i] << 24;
                    val += buf[4 * i + 1] << 16;
                    val += buf[4 * i + 2] << 8;
                    val += buf[4 * i + 3];

                read[i]=Float.valueOf(Integer.toBinaryString(val));

                //int val = Float.floatToRawIntBits(disparityMap[i]);

            }

            long ct_write = System.nanoTime();
            long offset_write = ct_write - timeBeforeWrite;
            float mOffsetInMs_write = (float)(offset_write)/1000000;
            Log.e("ETA", "read float[]  " + Float.toString(mOffsetInMs_write));

            dataIn.close();

        }catch (IOException ex) {
            System.err.println(ex.getMessage());
        }

things read back is pretty strange floating point values, and what's wrong with this?BTW, read back runs pretty slow, don't know why. Or any other good idea for fast read/write float array?

Thanks!

//Thanks to Larry, I have try bytebuffer.asfloatbuffer() ways like:

//WRITE
    float[] test = new float[3];
    test[0]=1.1f;
    test[1]=1.2f;
    test[2]=1.5f;
    try{
        RandomAccessFile aFile = new RandomAccessFile("/sdcard/demo.data", "rw");
        FileChannel outChannel = aFile.getChannel();

        //one float 3 bytes
        ByteBuffer buf = ByteBuffer.allocate(12);
        buf.clear();
        buf.asFloatBuffer().put(test);

        //while(buf.hasRemaining()) 
        {
            outChannel.write(buf);
        }

        outChannel.close();

    }
    catch (IOException ex) {
        System.err.println(ex.getMessage());
    }

    //READ
    float[] readback=new float[3];
    try{


        RandomAccessFile rFile = new RandomAccessFile("/sdcard/demo.data", "rw");
        FileChannel inChannel = rFile.getChannel();
        ByteBuffer buf_in = ByteBuffer.allocate(12);
        buf_in.clear();

        inChannel.read(buf_in);

        buf_in.asFloatBuffer().get(readback);

        inChannel.close();

    }
    catch (IOException ex) {
        System.err.println(ex.getMessage());
    }

and the program crashes in buf_in.asFloatBuffer().get(readback); any idea and is there goods ways to goes in and debug inside in java, Sorry completely new in java world. Thanks again

Community
  • 1
  • 1
flankechen
  • 1,225
  • 16
  • 31
  • I've the same problem as you... "buf_in.asFloatBuffer().get(readback);" crashes... Have you solved the problem? – adlagar Oct 19 '15 at 10:53
  • The problem missing here is that the position of the buffer is wrong. You need to call position(0) on it. – Jeffrey Drake Dec 03 '15 at 08:02

3 Answers3

7

Thanks to Larry, I am just sharing my codes and hopefully it helps someone else.

I just figure it out, we need to rewind to buffers after read/write to file channels. following codes just works, and runs pretty fast.

float[] disparity=new float[640*480];

    disparity[1]=1.5f;
    disparity[2]=4.566f;

//WRITE
    try{
        RandomAccessFile aFile = new RandomAccessFile("/sdcard/demo.data", "rw");
        FileChannel outChannel = aFile.getChannel();

        //one float 4 bytes
        ByteBuffer buf = ByteBuffer.allocate(4*640*480);
        buf.clear();
        buf.asFloatBuffer().put(disparity);

        //while(buf.hasRemaining()) 
        {
            outChannel.write(buf);
        }

        //outChannel.close();
        buf.rewind();

        float[] out=new float[3];
        buf.asFloatBuffer().get(out);

        outChannel.close();

    }
    catch (IOException ex) {
        System.err.println(ex.getMessage());
    }

    //READ
    float[] readback=new float[640*480];
    try{

        RandomAccessFile rFile = new RandomAccessFile("/sdcard/demo.data", "rw");
        FileChannel inChannel = rFile.getChannel();
        ByteBuffer buf_in = ByteBuffer.allocate(640*480*4);
        buf_in.clear();

        inChannel.read(buf_in);

        buf_in.rewind();
        buf_in.asFloatBuffer().get(readback);

        inChannel.close();

    }
    catch (IOException ex) {
        System.err.println(ex.getMessage());
    }

Thanks again.

flankechen
  • 1,225
  • 16
  • 31
  • You must close the file in a `finally` block or use `try-with-resources`! You are correct about rewinding during read, but not during write. I suggest you do: `try (ByteChannel channel = Files.newByteChannel( path, WRITE, CREATE, TRUNCATE_EXISTING )) { ByteBuffer buf = ByteBuffer.allocate(disparity.length * 4); buf.asFloatBuffer().put(disparity); channel.write (buf); }` – Aleksandr Dubinsky Dec 15 '14 at 20:08
6

Try using FileChannel for your file access and a ByteBuffer for the data. You can put the data into the ByteBuffer using the ByteBuffer.putFloat() methods and write it out with FileChannel.write(). When you read it back, you can call FileChannel.read() to get a ByteBuffer representing the data, then call ByteBuffer.asFloatBuffer() to get a FloatBuffer representing the data which can then be used to get a float[].

Larry Schiefer
  • 15,687
  • 2
  • 27
  • 33
  • thanks a lot and I have update my problems, read back is not working in buf_in.asFloatBuffer().get(readback); any ideas about this? – flankechen Mar 08 '14 at 08:42
0

Just add a BufferedOutputStream between your DataOutputStream and your FileOutputStream.

user207421
  • 305,947
  • 44
  • 307
  • 483