【问题标题】:How to extract used byte array from ByteBuffer?如何从 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 作为参数会更简单。你不应该像这样复制数据。

标签: java arrays guava nio 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() versionwithout 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() 将抛出以下任何异常。

  1. UnsupportedOperationException - 在直接缓冲区上调用它时。
  2. ReadOnlyBufferException - 如果缓冲区是只读的。

【讨论】:

    猜你喜欢
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 2019-08-15
    • 2020-01-03
    • 2015-04-14
    • 2017-03-02
    • 2013-03-15
    相关资源
    最近更新 更多