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
字段为 null
,array()
会抛出 UnsupportedOperationException
。如果您查看 Oracle JDK 7 的源代码,则有注释
final float[] hb; // Non-null only for heap buffers
如果您运行代码,您会注意到返回的 FloatBuffer
是 ByteBufferAsFloatBufferB
,而不是 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[]的主要内容,如果未能解决你的问题,请参考以下文章