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

Posted

技术标签:

【中文标题】如何从 ByteBuffer 中获取已使用的 byte[]【英文标题】:How to obtain used byte[] from ByteBuffer 【发布时间】:2015-02-01 05:47:38 【问题描述】:

java.nio.ByteBuffer 类有一个ByteBuffer.array() 方法,但是它返回的数组是缓冲区容量的大小,而不是已用容量。因此,我遇到了很多问题。

我注意到使用 ByteBuffer.remaining() 可以得到缓冲区当前正在使用的字节数,所以基本上我正在寻找一种方法来获取仅使用的字节的 byte[] . (即ByteBuffer.remaining()中显示的字节数。

我尝试了一些不同的方法,但似乎都失败了,我能想到的唯一解决方法是使用分配的剩余缓冲区大小创建另一个 ByteBuffer,然后向其中写入 (x) 个字节.

【问题讨论】:

【参考方案1】:

从阅读Javadocs 开始,我认为剩余只会为您提供当前位置和限制之间的字节数。

剩余()

返回当前位置和限制之间的元素数量。

此外:

缓冲区的容量是它包含的元素数量。缓冲区的容量永远不会是负数,也永远不会改变。

缓冲区的限制是不应读取或写入的第一个元素的索引。缓冲区的限制永远不会是负数,也永远不会大于其容量。

缓冲区的位置是要读取或写入的下一个元素的索引。缓冲区的位置永远不会是负数,也永远不会超过其限制。

所以考虑到这一切如何:

static byte[] getByteArray(ByteBuffer bb) 
    byte[] ba = new byte[bb.limit()];
    bb.get(ba);
    return ba;

这使用了ByteBuffer的get(byte[] dst)方法

公共字节缓冲区获取(字节[] dst)

相对批量获取方法。 此方法将此缓冲区中的字节传输到给定的目标数组中。 src.get(a) 形式的此方法的调用与调用的行为方式完全相同

 src.get(a, 0, a.length) 

【讨论】:

这个有bug,你要bb.rewind();在 bb.get(ba) 之前;声明,否则这将抛出 BufferUnderflowException。即,如果缓冲区中剩余的字节数少于满足请求所需的字节数,也就是说,如果 length > remaining(),则不传输任何字节并抛出 BufferUnderflowException【参考方案2】:

如有必要,分配一个byte[],然后使用ByteBuffer.get(byte[])ByteBuffer.get(byte[], int, int) 方法将字节复制到数组中。根据ByteBuffer 的状态,您可能需要先flip

在某些情况下,还可以获得ByteBuffer 的支持数组,但不推荐 ...

更多详情,javadocs 是here。

【讨论】:

以上是关于如何从 ByteBuffer 中获取已使用的 byte[]的主要内容,如果未能解决你的问题,请参考以下文章

如何从 ByteBuffer 中提取使用过的字节数组?

JNA ByteBuffer statvfs

如何使用 ReadableByteChannel 获取文件内容并将其存储在 byteBuffer 中?

从 ByteBuffer 获取到 byte[] 不写入到 byte[]

JNI从ByteBuffer获取数据,返回byte[]

如何在 JNI 中将 char[] 转换为 ByteBuffer?