Java NIO ByteBuffer,翻转后写入



我是Java ByteBuffers的新手,想知道在翻转ByteBuffer后写入ByteBuffer的正确方法是什么。

在我的用例中,我正在将输出缓冲区写入套接字:

outBuffer.flip();
//Non-blocking SocketChannel
int bytesWritten = getSocket().write(outBuffer);

在此之后,必须再次写入输出缓冲区。此外,并非 outBuffer 中的所有字节都已写入套接字。

由于它当前已翻转,如果它仍在缓冲区中并且未写入套接字,我如何使其再次可写,而不会覆盖任何数据?

如果我是对的,outBuffer.position() == bytesWrite和限制应该是要写入的数据量。

那么使用以下方法来重用输出缓冲区是正确的吗?

int limit = outBuffer.limit()  
outBuffer.limit(outBuffer.capacity());
outBuffer.position(limit);

同样来自 API 规范:以下循环通过缓冲区 buf 将字节从一个通道复制到另一个通道:

while (in.read(buf) >= 0 || buf.position != 0) {
buf.flip();
out.write(buf);
buf.compact();    // In case of partial write
}

因为它目前是翻转的

它将保持翻转状态。写入不会改变这一点。

如果它仍在缓冲区中并且未写入套接字,如何使其再次可写,而不会覆盖任何数据?

你不需要做任何事情,但是如果你想在再次写之前阅读,你应该做翻转/写/压缩。如果您只想重复写入,只需再次调用write(),缓冲区仍处于当前状态。

但我更喜欢始终保持这些缓冲区准备好读取,这样就不会出错,并且在必要时进行原子操作时翻转/写入/压缩(或翻转/获取/压缩)。

请注意,您不应该使用clear(),除非您确定写入已完成并且缓冲区现在为空。在这种情况下,紧凑和清晰是等效的。但始终紧凑更简单。

如果在阻止模式下复制,请使用 @zlakad 引用的循环。