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

2
  • I've the same problem as you... "buf_in.asFloatBuffer().get(readback);" crashes... Have you solved the problem? Commented Oct 19, 2015 at 10:53
  • The problem missing here is that the position of the buffer is wrong. You need to call position(0) on it. Commented Dec 3, 2015 at 8:02

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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); }
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[].

1 Comment

thanks a lot and I have update my problems, read back is not working in buf_in.asFloatBuffer().get(readback); any ideas about this?
0

Just add a BufferedOutputStream between your DataOutputStream and your FileOutputStream.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.