11

我遇到了这个查询:Create a ByteBuf in Netty 4.0 about conversion from byte[] to ByteBuf and ByteBuffer to ByteBuf。我很想知道以另一种方式进行的转换:

io.netty.buffer.ByteBuf 到 java.nio.ByteBuffer

以及如何有效地做到这一点,最少/不复制?我做了一些阅读,经过反复试验,我发现这种转换方式效率低下(有两份):

// io.netty.handler.codec.http.FullHttpRequest fullHttpRequest;
ByteBuf conByteBuf = fullHttpRequest.content ();                  
int numReadBytes = conByteBuf.readableBytes ();
conBytes = new byte[numReadBytes];
conByteBuf .readBytes (conBytes);                                // First Copy
ByteBuffer conByteBuffer = ByteBuffer.allocate (conBytes.length);
conByteBuffer.put (conByteBuf);                                  // Second Copy

我的问题是,我们能否避免一个或两个副本,并使 ByteBuffer 的内部缓冲区使用 ByteBuf 的内部缓冲区。

谢谢!

4

3 回答 3

12

您应该能够使用ByteBuf.nioBuffers()。它将返回一个ByteBufByteBuffer 对象数组的视图。

在大多数情况下,这个数组只有一个元素,但在一些更复杂的实现中ByteBuf,可能有多个底层 ByteBuffer 对象,并且ByteBuf.nioBuffers()可以按原样返回它们,而不是像调用ByteBuf.nioBuffer().

您可以通过使用提前知道数组长度是多少ByteBuf.nioBufferCount()

于 2013-10-10T20:25:19.747 回答
7

您至少可以使用ByteBuffer.wrap()以避免第二次复制。

于 2013-10-10T18:56:44.900 回答
2

不是特别有效,但可以解决问题:

public static ByteBuffer toNioBuffer(ByteBuf buffer) {
    if (buffer.isDirect()) {
        return buffer.nioBuffer();
    }
    final byte[] bytes = new byte[buffer.readableBytes()];
    buffer.getBytes(buffer.readerIndex(), bytes);
    return ByteBuffer.wrap(bytes);
}
于 2015-08-28T01:45:56.853 回答