我想使用FileChannels#transferFrom将从 SocketChannel 接收的Netty DirectByteBuf零复制到文件中。我利用 ReadableByteChannel 接口创建了一个 ByteChannel 来读取,如下所示:
public static void zeroCopyFile(FileChannel targetChannel, ByteBuf content) {
targetChannel.transferFrom(new ByteBufChannel(content), 0, content.readableBytes());
}
private static class ByteBufChannel implements ReadableByteChannel {
private final ByteBuf byteBuf;
private final int MAX_SIZE = 4096;
public ByteBufChannel(ByteBuf byteBuf) {
this.byteBuf = byteBuf;
}
@Override
public boolean isOpen() {
return true;
}
@Override
public void close() throws IOException {
}
@Override
public int read(ByteBuffer dst) throws IOException {
int byteBufReadableBytes = Math.min(MAX_SIZE, byteBuf.readableBytes());
dst.put(byteBuf.nioBuffer(byteBuf.readerIndex(), byteBufReadableBytes));
byteBuf.readerIndex(byteBufReadableBytes+byteBuf.readerIndex());
return byteBufReadableBytes - byteBuf.readableBytes();
}
}
调试它表明这ByteBuffer dst
是一个 HeapByteBuffer。这样零拷贝是不可能的。有没有机会在ByteBuf content
不触及用户空间的情况下让我进入文件?我真的必须将 SocketChannel 直接读入文件吗?
更新
调试FileChannel
使我意识到,这transferFrom
仅适用于文件到文件的传输。一个简单fileChannel.write(directBuffer)
的应该做零拷贝。唯一让我有点困扰的是我的 corretto java 无法加载write0
. 这是否意味着性能较低或是否意味着副本不是零副本?