UnsupportedOperationException 将 byte[] 转换为 float[]

Posted

技术标签:

【中文标题】UnsupportedOperationException 将 byte[] 转换为 float[]【英文标题】:UnsupportedOperationException with converting byte[] to float[] 【发布时间】:2013-11-06 14:20:29 【问题描述】:

我正在尝试将 byte[] 转换为 float[],方法是将 byte[] 放入 ByteBuffer,将其转换为 FloatBuffer (.asFloatBuffer),然后将其转换为数组。

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

但是运行:

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

给我一​​个java.lang.UnsupportedOperationException at java.nio.FloatBuffer.array(Unknown Source)。 我相信文档说该错误与没有数组支持的缓冲区有关 (???)。

任何人都知道如何解决这个问题,或者我应该如何将此数组转换为浮点数?

【问题讨论】:

我很想您应该“更深入”并尝试以 float[] 而不是 byte[] 开头。除此之外,您可以在包装的缓冲区上调用 #getFloat() ,直到输入用完为止。 【参考方案1】:
    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;
    

例如:

     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));

【讨论】:

这很好用!另一个答案也很好,但我更喜欢这个,因为不需要循环。 解释一下怎么样?【参考方案2】:

从被ByteBuffer 包裹的byte[] 数组中获取float 的简单方法是使用getFloat(),它读取接下来的4 个字节并返回生成的float。如果您的 byte[] 包含超过 4 个字节,您可以循环执行此操作。请注意,该方法会抛出

BufferUnderflowException - 如果少于四个字节 留在这个缓冲区中

您也可以从FloatBuffer 获得它

buffer.asFloatBuffer().get();

如果您愿意,但如果实例的 hb 字段为 nullarray() 会抛出 UnsupportedOperationException。如果您查看 Oracle JDK 7 的源代码,则有注释

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

如果您运行代码,您会注意到返回的 FloatBufferByteBufferAsFloatBufferB,而不是 HeapFloatBuffer

【讨论】:

我明天试试这个。但是如果我理解正确的话,asFloatBuffer() 实际上并没有转换类型,而只是改变了字节数组的解释方式? @user 好像。 Javadoc 状态 Creates a view of this byte buffer as a float buffer. 是的,这就是为什么当您执行“return ByteBuffer.wrap(bytes).asFloatBuffer().array();”时会导致错误的原因因为真正的字节是分配的内存。它不能让 float[] 和 byte[] 数组指向同一个内存。【参考方案3】:
public static float[] toFloatArray(byte[] bytes) 
    float[] floats = new float[bytes.length/4];
    ByteBuffer.wrap(bytes).asFloatBuffer().get(floats).array();
    return floats;

你不能做return ByteBuffer.wrap(bytes).asFloatBuffer().array(); 的原因是它将这个字节缓冲区创建为一个浮动缓冲区的视图。这意味着它使用相同的内存。它的速度快如闪电,但需要一个地方将其放入不被视为 float[] AND byte[] 的内存中,因此它为什么不能在没有新内存的情况下将数据返回给您。

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

只是这个类没有自己的记忆,而是摆弄你给它的记忆,这很棒,但有时可能会让人困惑。

【讨论】:

以上是关于UnsupportedOperationException 将 byte[] 转换为 float[]的主要内容,如果未能解决你的问题,请参考以下文章