【问题标题】:UnsupportedOperationException with converting byte[] to float[]UnsupportedOperationException 将 byte[] 转换为 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() ,直到输入用完为止。

标签: java arrays exception byte buffer


【解决方案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);
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 2014-07-21
    相关资源
    最近更新 更多