如何从 ByteBuffer 中提取使用过的字节数组?
Posted
技术标签:
【中文标题】如何从 ByteBuffer 中提取使用过的字节数组?【英文标题】:How to extract used byte array from ByteBuffer? 【发布时间】:2018-03-14 23:08:57 【问题描述】:java.nio.ByteBuffer
类有一个ByteBuffer.array()
方法,但是这会返回一个数组,该数组是缓冲区容量的大小,而不是已用容量。因此,我遇到了一些问题。
我有一个字节缓冲区,我将其分配为某种大小,然后我将数据插入到它。
ByteBuffer oldBuffer = ByteBuffer.allocate(SIZE);
addHeader(oldBuffer, pendingItems);
newBuffer.flip();
oldBuffer.put(newBuffer);
// as of now I am sending everything from oldBuffer
send(address, oldBuffer.array());
我怎样才能发送oldBuffer
中正在使用的内容。有没有一种班轮可以做到这一点?
【问题讨论】:
修改send()
方法以接受长度(和偏移量)或将实际ByteBuffer
作为参数会更简单。你不应该像这样复制数据。
【参考方案1】:
您可以翻转缓冲区,然后使用缓冲区的剩余大小创建一个新数组并填充它。
oldBuffer.flip();
byte[] remaining = new byte[oldBuffer.remaining()];
oldBuffer.get(remaining);
flip()
和 Arrays.copyOf 的另一种方式
oldBuffer.flip();
Arrays.copyOf(oldBuffer.array(), oldBuffer.remaining());
没有flip()
Arrays.copyOf(oldBuffer.array(), oldBuffer.position());
也像 EJP 说的,如果你可以访问send(..)
方法,你可以在send()
方法中添加一个大小和偏移量参数,而无需创建和填充一个新数组。
【讨论】:
是的,我确实可以使用send
方法,那么我们可以对其进行哪些更改?你能举个例子来说明一下吗?
这取决于您如何处理send
方法中的数据,如果您最终需要该长度的数组,您可以这样做,只需调用send(..)
方法和无需修改任何东西。此外,如果数据不多,您可以复制数组。
是的,我确实需要那个长度的发送方法中的字节数组。 with flip() version
与 without flip() version
之间还有什么区别?
好吧,如果迟早你需要那个长度的数组,那么你可以早点做。 Flip()
更改ByteBuffer
的限制、位置和标记值,通常在读取前使用。数组是一样的,所以实际上差别不大,如果你不再使用那个缓冲区,根本没有差别。【参考方案2】:
缓冲区的position()
表示缓冲区中使用的数据量。
所以创建一个该大小的字节数组。
接下来转到缓冲区的位置 0,因为您必须从那里读取数据。 rewind()
这样做。
然后使用get()
方法将缓冲区数据复制到数组中。
byte[] data = new byte[buffer.position()];
buffer.rewind();
buffer.get(data);
另请注意,buffer.array()
仅在 buffer.hasArray()
返回 true 时有效。所以在调用它之前检查hasArray()
。否则,buffer.array()
将抛出以下任何异常。
UnsupportedOperationException
- 在直接缓冲区上调用它时。
ReadOnlyBufferException
- 如果缓冲区是只读的。
【讨论】:
以上是关于如何从 ByteBuffer 中提取使用过的字节数组?的主要内容,如果未能解决你的问题,请参考以下文章