12

I'm trying to convert a byte[] to a float[] by putting the byte[] in a ByteBuffer, converting this to a FloatBuffer (.asFloatBuffer), and then converting this to an array.

private static float[] toFloatArray(byte[] bytes) {
    ByteBuffer buffer = ByteBuffer.wrap(bytes);
    return buffer.asFloatBuffer().array();
}

However running:

 byte[] bytes = {14,32,26,21};
          toFloatArray(bytes);

Gives me a java.lang.UnsupportedOperationException at java.nio.FloatBuffer.array(Unknown Source). I believe the documentation says that the error has something to do with the buffer not being backed by an array (???).

Anyone has an idea how to fix this, or how I SHOULD convert this array to floats?

1
  • I'm tempted to think that you should be going "deeper" and trying to get a float[] to begin with instead of a byte[]. Barring that, you could just call #getFloat() on the wrapped buffer until you run out of input. Commented Oct 27, 2013 at 22:10

3 Answers 3

17
    private static float[] toFloatArray(byte[] bytes) {
        ByteBuffer buffer = ByteBuffer.wrap(bytes);
        FloatBuffer fb = buffer.asFloatBuffer();

        float[] floatArray = new float[fb.limit()];
        fb.get(floatArray);


        return floatArray;
    }

ex:

     byte[] bytes = {65,-56,0,0 , 65,-56,0,0};
     float[] result = toFloatArray(bytes);   

     //print 25.0 25.0
     System.out.println(Arrays.toString(result));
Sign up to request clarification or add additional context in comments.

1 Comment

What about some explanation?
2

The simple way to get a float from a byte[] array wrapped by a ByteBuffer is to use getFloat() which reads the next 4 bytes and returns the generated float. You can do this in a loop, if your byte[] contains more than 4 bytes. Note that the method throws

BufferUnderflowException - If there are fewer than four bytes remaining in this buffer

You can get it from the FloatBuffer as well

buffer.asFloatBuffer().get();

if you want but array() throws an UnsupportedOperationException if the instance's hb field is null. If you look at the source code from Oracle JDK 7, there is a comment

final float[] hb;  // Non-null only for heap buffers

If you run your code, you will notice the returned FloatBuffer is a ByteBufferAsFloatBufferB, not a HeapFloatBuffer.

3 Comments

I will try this tomorrow. But if I understand it correctly, asFloatBuffer() doesnt actually convert the type, but only changes how the byte array is interpreted?
@user Seems like it. Javadoc states Creates a view of this byte buffer as a float buffer.
Yes, which is why it causes an error when you do "return ByteBuffer.wrap(bytes).asFloatBuffer().array();" because really bytes is the memory that is allocated. It can't allow a float[] and byte[] array to point to the same memory.
1
public static float[] toFloatArray(byte[] bytes) {
    float[] floats = new float[bytes.length/4];
    ByteBuffer.wrap(bytes).asFloatBuffer().get(floats).array();
    return floats;
}

The reason why you can't do return ByteBuffer.wrap(bytes).asFloatBuffer().array(); is that it creates a view of this byte buffer as a float buffer. Which means it's using the same memory. It's lightning fast, but needs a place to put it in memory that isn't being treated as a float[] AND byte[] hence why it can't give you the data back without new memory.

public static void convertFloatArray(byte[] bytes, float[] floats) {
    ByteBuffer.wrap(bytes).asFloatBuffer().get(floats,0,bytes.length/4);
}

It's just the class doesn't make its own memory but fiddles with the memory you give it, which is awesome, but could be confusing at times.

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.