106

为什么ByteBuffer的flip()方法叫“flip”?这里“翻转”了什么?根据 apidoc,连续两次翻转不会恢复原始状态,多次翻转可能会趋于limit()为零。

我可以以某种方式“取消翻转”以重用超出限制的字节吗?

我可以连接尾部以与其他一些数据翻转吗?

4

4 回答 4

141

一个相当常见的用例ByteBuffer是逐个构建一些数据结构,然后将整个结构写入磁盘。flip用于ByteBuffer从“从I/O读取”(putting)翻转到“写入I/O”(getting):使用s序列put填充后ByteBufferflip将缓冲区的限制设置为当前位置并将位置重置为零。这具有使未来getwrite从缓冲区写入所有内容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);
}
于 2013-02-09T23:56:54.780 回答
12

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

于 2018-05-23T05:30:14.483 回答
2

ByteBuffer 设计不当。体面的程序员有很多抱怨。

所以不要试图去推理它,只要仔细研究和使用 API。

现在我不能在没有提出替代方案的情况下说它,所以这里是:

缓冲区有一个固定的capacity;它维护 2 个指针:startend. get()返回该start位置的字节并递增startput()将字节放在end位置并递增end。不flip()

于 2013-02-10T01:36:26.730 回答
2

flip()方法使缓冲区为新的通道写入或相对获取操作序列做好准备:它将限制设置为当前位置,然后将位置设置为零。

缓冲区跟踪写入其中的数据。写入后,调用flip()方法从写入模式切换到读取模式。

于 2018-08-29T14:22:59.963 回答