为什么ByteBuffer的flip()方法叫“flip”?这里“翻转”了什么?根据 apidoc,连续两次翻转不会恢复原始状态,多次翻转可能会趋于limit()
为零。
我可以以某种方式“取消翻转”以重用超出限制的字节吗?
我可以连接尾部以与其他一些数据翻转吗?
为什么ByteBuffer的flip()方法叫“flip”?这里“翻转”了什么?根据 apidoc,连续两次翻转不会恢复原始状态,多次翻转可能会趋于limit()
为零。
我可以以某种方式“取消翻转”以重用超出限制的字节吗?
我可以连接尾部以与其他一些数据翻转吗?
一个相当常见的用例ByteBuffer
是逐个构建一些数据结构,然后将整个结构写入磁盘。flip
用于ByteBuffer
从“从I/O读取”(put
ting)翻转到“写入I/O”(get
ting):使用s序列put
填充后ByteBuffer
,flip
将缓冲区的限制设置为当前位置并将位置重置为零。这具有使未来get
或write
从缓冲区写入所有内容put
到缓冲区中的效果,而不是更多。
完成后put
,您可能希望重用ByteBuffer
来构造另一个数据结构。要“取消翻转”它,请调用clear
. 这会将限制重置为容量(使所有缓冲区都可用),并将位置重置为 0。
所以,一个典型的使用场景:
ByteBuffer b = new ByteBuffer(1024);
for(int i=0; i<N; i++) {
b.clear();
b.put(header[i]);
b.put(data[i]);
b.flip();
out.write(b);
}
Flip 将当前位置值分配给 limit 属性并将 position 属性设置为 0。 Flip 对于仅从缓冲区中排出活动元素很有用。
例如,下面的程序打印“hello”而不是缓冲区的空元素。方法调用限制和位置可以用翻转代替。
CharBuffer cbuff = CharBuffer.allocate(40);
cbuff.put("hello");
// what below two line of code is what flip does
cbuff.limit(cbuff.position());
cbuff.position(0);
while(cbuff.hasRemaining()) {
System.out.println(cbuff.get());
}
有关缓冲区和通道的更多信息,请参阅http://www.zoftino.com/java-nio-tutorial。
ByteBuffer 设计不当。体面的程序员有很多抱怨。
所以不要试图去推理它,只要仔细研究和使用 API。
现在我不能在没有提出替代方案的情况下说它,所以这里是:
缓冲区有一个固定的capacity
;它维护 2 个指针:start
和end
. get()
返回该start
位置的字节并递增start
。put()
将字节放在end
位置并递增end
。不flip()
!
flip()方法使缓冲区为新的通道写入或相对获取操作序列做好准备:它将限制设置为当前位置,然后将位置设置为零。
缓冲区跟踪写入其中的数据。写入后,调用flip()方法从写入模式切换到读取模式。