bytebuffer.flip()和bytebuffer.rewind()之间的区别

时间:2013-05-09 12:00:38

标签: java io nio

我知道flip()将当前缓冲区位置设置为0并将限制设置为前一个缓冲区位置,而rewind()只将当前缓冲区位置设置为0。

在下面的代码中,我使用rewind()或flip()获得相同的结果。

byte b = 127;
bb.put(b);
bb.rewind();//or flip();

System.out.println(bb.get());
bb.rewind();// or flip();
System.out.println(bb.get());

你能否提供一个真实的例子,这两种方法的区别真的很重要?提前致谢。 编辑:我在this链接中找到了解决方案,对于缓冲区和通道类的使用有详尽的解释和详细说明。

6 个答案:

答案 0 :(得分:12)

从源代码来看,它们非常相似。您可以看到以下内容:

public final Buffer flip() {
    limit = position;
    position = 0;
    mark = -1;
    return this;
}

public final Buffer rewind() {
    position = 0;
    mark = -1;
    return this;
}

所以区别在于fliplimit设置为position,而rewind则没有。 考虑你已经分配了一个8字节的缓冲区,你已经用4个字节填充了缓冲区,然后将位置设置为3,只显示如下:

    [ 1  1  1  1  0  0  0  0]
               |           |
flip           limit       |
rewind                     limit

所以rewind刚刚使用的限制设置得恰当。

答案 1 :(得分:9)

它们根本不相同。

ByteBuffer通常已准备好read()(或put())。

flip()write()(或get())做好准备。

rewind()以及compact()clear()read()/put()(或write())后再次为get()做好准备。

答案 2 :(得分:1)

rewind()方法类似于flip()但不影响限制。它只将位置设置回0.您可以使用rewind()返回并重新读取已经翻转的缓冲区中的数据。一个常见的情况是:在你使用flip()之后,你从缓冲区中读取数据,你想重新读取数据,这个方法就可以了。

答案 3 :(得分:1)

以下是两个会产生不同结果的示例。 正如你所说,两者都将位置设置为0,两者之间的差异是翻转将限制设置为前一个位置。

因此,对于翻转,如果您正在编写(put),则读取限制(get)将成为您编写的最后一个元素的位置。如果您尝试阅读更多内容,则会引发异常。

倒带使限制保持不变。假设它处于容量(缓冲区大小),它将让你继续读取超出实际写入的数据,在这种情况下读取缓冲区初始化的初始零。

ByteBuffer bb = ByteBuffer.allocateDirect(2);
byte b = 127;
bb.put(b);
bb.rewind();//or flip();

System.out.println(bb.get());  // will print 127 in either case
System.out.println(bb.get());  // will print 0 for rewind, BufferUnderflow exception for flip

答案 4 :(得分:1)

缓冲区具有位置,限制和容量属性。您可以在创建缓冲区时为n个元素分配空间。这里n是容量。分配缓冲区后,position设置为0,limit设置为capacity。

如果用n-x个元素填充缓冲区,则位置将设置为n-x。在n-x之后缓冲区将具有空元素。

如果您想在此时排空缓冲区并且只想要非空值,则需要将当前位置和位置限制设置为零。使用hasRemaining(),您可以获得直到n-x的元素。翻转设置如上所述的限制和位置属性。

翻转和倒带之间的区别在于翻转将位置设置为0并将活动内容设置为限制。方法回放只是将位置设置为0。

了解更多信息http://www.zoftino.com/java-nio-tutorial

答案 5 :(得分:0)

@ user963241在@ EJP的回答中添加更多颜色。

  

flip()使它为write()(或get())

做好准备

get()示例;

您可能希望从缓冲区中读取数据 假设您最初将其存储在那里)并将其用于其他内容例如转换为字符串并对其进行操作以供进一步使用。

ByteBuffer buf = ByteBuffer.allocateDirect(80);
private String method(){
buf.flip();
byte[] bytes = byte[10]; //creates a byte array where you can place your data 
buf.get(bytes); //reads data from buffer and places it in the byte array created above
return bytes;
}

write()示例; 从套接字通道读取数据到缓冲区后,您可能希望将其写回套接字通道 - 假设您要实现像服务器那样从客户端收到相同消息的东西。

因此,您将从通道读取到缓冲区,从缓冲区读回通道

SocketChannel socketChannel = SocketChannel.open();
...

ByteBuffer buf = ByteBuffer.allocateDirect(80);

int data = socketChannel.read(buf); // Reads from channel and places it into the buffer
while(data != -1){ //checks if not end of reading
buf.flip();        //prepares for writing
....
socketChannel.write(buf) // if you had initially placed data into buf and you want to read 
                         //from it so that you can write it back into the channel


  }