ByteBuffer的flip方法的目的是什么?(为什么将其称为“翻转”?)


95

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

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

我可以将尾部与其他数据连接起来吗?


5
它将缓冲区从读取“翻转”到写入(反之亦然)。由此hw.blogspot.com/2009/10/…–
Brian Roach

2
@BrianRoach:它会从读取翻转到写入,但对写入读取没有帮助,除非您正在编写固定大小的结构。如果要翻转以进行读写操作,请reset改用。
nneonneo 2013年

记住要问“客观”问题;或至少使主要问题显得客观:D

@nneonneo-这是一个毫无疑问的问题,实际上不会花很多时间来解释细节,因此只是一个评论和链接。
布赖恩·罗奇

Answers:


130

一个相当普遍的用例ByteBuffer是逐个构造一些数据结构,然后将整个结构写入磁盘。flip用于将ByteBuffer“从I / O读取”(putting)切换为“写入I / O”(getting):put使用s序列填充后ByteBufferflip会将缓冲区的限制设置为当前位置并将位置重置为零。这具有使futuregetwrite从缓冲区写入所有内容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);
}

什么是out
Suzan Cioc

6
或其他任何具有write(ByteBuffer)方法的东西。(它的类型到底有多大关系……)
Stephen C

1
应该Buffer.clear将容量和位置的限制Buffer.reset重置为0。仅将位置重置为mark
Kelvin Ng

1
@KelvinNg:你是对的;我修改了答案以反映这一点。感谢您的好收获!
nneonneo

1
@ user963241:I / O读取到缓冲区,缓冲区写入I / O。
nneonneo

7

翻转将当前位置值分配给limit属性,并将position属性设置为0。翻转仅用于从缓冲区中清空活动元素。

例如,下面的程序打印“ hello”不是缓冲区的空元素。方法调用的限制和位置可以用flip替换。

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


感谢您链接到非常广泛的报道!包含来源时真是太好了。Java API文档似乎在没有解释的情况下使用了“翻转”一词,就好像它是计算机科学的通用术语一样,但是显然,包括我在内的一些人都没有发现这种情况。
约翰·迈耶

3

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

因此,请勿尝试推理,只需仔细研究和使用API​​。

现在,我不能不提出替代方案而对其作废,所以这里是:

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


6
那么,有哪些投诉?如果您也有个人的不满,但是不要仅仅说“ X API很烂,人们这样说”。
nneonneo

13
实际上,发布该链接实际上是您要做的所有事情。我从来没有指责过你说谎,我只是请你详细说明投诉的来源和性质。
nneonneo

2
这只是人们自愿选择的适当位置,人们自愿提供帮助的地方。我不需要将每个答案扩展到研究透彻的学术论文中。
无可争议的

8
在这里,除非听起来可信,否则人们不会相信别人的话。
arunmoezhi13年

8
您甚至不需要提供来源。显然,ByteBuffer设计不当。flip并没有达到目的,只是在您忘记翻转时引入了一个错误源。如果他们想放一个不可控制的冲动,请至少将翻转和翻转的ByteBuffers设置为不同的类,以便类型系统可以捕获错误。
Gurgeh

0

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.