从 ByteBuffer 到双数组

Posted

技术标签:

【中文标题】从 ByteBuffer 到双数组【英文标题】:From ByteBuffer to double array 【发布时间】:2016-04-03 10:57:35 【问题描述】:

我有一个 ByteBuffer 包含三个双精度值,例如1.0, 2.0, 3.0。我现在拥有的是

double[] a = new double[3];
for (int i = 0; i < 3; i++) 
    a[i] = byteBuffer.getDouble();

效果很好,但我更喜欢通过

的一步解决方案
double[] a = byteBuffer.asDoubleBuffer().array();

但这会导致异常:

java.lang.UnsupportedOperationException at java.nio.DoubleBuffer.array(...)

我做错了什么?

【问题讨论】:

【参考方案1】:

您误用了DoubleBufferDoubleBuffer.array() 返回支持DoubleBuffer 的数组当且仅当它是一种由数组支持的DoubleBuffer。这个不是。它由ByteBuffer 支持。其实这个DoubleBuffer只是对原ByteBuffer的一个看法。

您可以通过调用hasArray() 方法来确定任何特定的ByteBuffer 是否由数组支持。

有关将DoubleBuffer 的内容放入double 数组的代码,请参见Peter Lawrey 的答案。 (他打败了我。:-))

【讨论】:

【参考方案2】:

DoubleBuffer 有两种模式:既可以通过分配工作,也可以作为视图工作。这是在创建DoubleBuffer 时专门决定的。

array() 方法是可选的,如果您从视图中使用它,将抛出 UnsupportedOperationException

在您的情况下,使用ByteBuffer::asDoubleBuffer 方法从ByteBufferDoubleBuffer,您会得到一个视图,如Javadoc 中所述。因为它是一个视图,所以你得到了例外。

【讨论】:

【参考方案3】:

根据documentation,array是可选操作:

public final double[] array()

返回支持此缓冲区的双精度数组(可选操作)。

您可以通过调用hasArray() 来判断调用array 是否正常。

您可以按如下方式制作数组:

DoubleBuffer dbuf = byteBuffer.asDoubleBuffer(); // Make DoubleBuffer
double[] a = new double[dbuf.remaining()]; // Make an array of the correct size
dbuf.get(a);                               // Copy the content into the array

【讨论】:

在我看来这应该是公认的答案,因为它不仅解释了我的错误,而且实际上给出了一个可行的解决方案。【参考方案4】:

你可以用这个复制到double[]

double[] doubles = new double[byteBuffer.remaining() / Double.BYTES];
byteBuffer.asDoubleBuffer().get(doubles);

【讨论】:

那是我缺少的部分。谢谢!

以上是关于从 ByteBuffer 到双数组的主要内容,如果未能解决你的问题,请参考以下文章

如何从 ByteBuffer 转换为 Integer 和 String?

如何从 ByteBuffer 中获取已使用的 byte[]

ByteBuffer类学习

ByteBuffer 介绍及 C++ 实现

ByteBuffer 介绍及 C++ 实现

将 C 字节数组解析为 Java ByteBuffer。