简体   繁体   English

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

[英]difference between bytebuffer.flip() and bytebuffer.rewind()

I am aware that flip() set the current buffer position to 0 and set the limit to the previous buffer position whereas rewind() just set the current buffer position to 0.我知道 flip() 将当前缓冲区位置设置为 0 并将限制设置为前一个缓冲区位置,而 rewind() 只是将当前缓冲区位置设置为 0。

In the following code, either I use rewind() or flip() i get the same result.在下面的代码中,我使用 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());

Could you provide me with a real example where the difference of these 2 methods really matters?你能给我提供一个真实的例子,说明这两种方法的区别真的很重要吗? Thanks in advance.提前致谢。

From the source code, they are very similar.从源代码来看,它们非常相似。 You can see the follow:您可以看到以下内容:

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

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

So the difference is the flip set the limit to the position , while rewind not.所以区别在于flip设置了positionlimit ,而rewind没有。 Consider you have allocated a buffer with 8 bytes, you have filled the buffer with 4 bytes, then the position is set to 3, just show as follow:假设你分配了一个8字节的缓冲区,你已经用4个字节填充了缓冲区,那么位置设置为3,如下所示:

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

So rewind just used limit has set appropriately.所以rewind刚刚使用的限制已适当设置。

They're not equivalent at all.它们根本不等价。

A ByteBuffer is normally ready for read() (or for put() ). ByteBuffer通常准备好用于read() (或用于put() )。

flip() makes it ready for write() (or for get() ). flip()使其为write() (或get() )做好准备。

rewind() and compact() and clear() make it ready for read()/put() again after write() (or get() ). rewind()compact()clear()write() (或get() )之后再次准备好read()/put() ) 。

The rewind( ) method is similar to flip( ) but does not affect the limit. rewind() 方法类似于flip(),但不影响限制。 It only sets the position back to 0. You can use rewind( ) to go back and reread the data in a buffer that has already been flipped.它只将位置重新设置为 0。您可以使用 rewind() 返回并重新读取已经翻转的缓冲区中的数据。 A common situation would be : after you use flip(), you read the data from the buffer, the you want to reread the data, this method would work.一种常见的情况是:在您使用 flip() 之后,您从缓冲区读取数据,您想重新读取数据,此方法将起作用。

Here is an example where the two will produce different results.这是一个示例,其中两者将产生不同的结果。 As you said, both set position to 0, the difference between the two is that flip sets the limit to the previous position.正如你所说,两者都将位置设置为0,两者之间的区别在于翻转将限制设置为前一个位置。

So with flip, if you were writing ( put ) , the limit for reading ( get ) will become the position of the last element you wrote.因此,使用 flip 时,如果您正在写入 ( put ) ,则读取限制 ( get ) 将成为您写入的最后一个元素的位置。 If you try to read any more than that, it will throw an exception.如果您尝试阅读更多内容,它将引发异常。

Rewind leaves the limit unchanged.倒带使限制保持不变。 Assuming it was at capacity ( buffer size ) , it will let you keep on reading beyond the data that you actually wrote, in this case reading the initial zeros that the buffer was initialized with.假设它已达到容量(缓冲区大小),它将让您继续读取超出实际写入的数据,在这种情况下读取缓冲区初始化的初始零。

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

Buffer has position, limit and capacity properties.缓冲区具有位置、限制和容量属性。 You can allocate space for n number of elements while creating a buffer.您可以在创建缓冲区时为 n 个元素分配空间。 Here n is the capacity.这里 n 是容量。 After buffer is allocated, position is set to 0 and limit is set to capacity.分配缓冲区后,位置设置为 0,限制设置为容量。

If you filled the buffer with nx number of elements, position will be set to nx.如果用 nx 个元素填充缓冲区,则位置将设置为 nx。 Buffer will have empty elements after nx.缓冲区将在 nx 之后有空元素。

If you want to drain the buffer at this point and that too want only non empty values, you need set limit to current position and position to zero.如果此时您想排空缓冲区并且只想要非空值,则需要将当前位置的限制和位置设置为零。 Using hasRemaining(), you can get elements till nx.使用 hasRemaining(),您可以获得元素直到 nx。 Flip sets the limit and position properties like described above.翻转设置限制和位置属性,如上所述。

Difference between flip and rewind is that flip sets the position to 0 and sets limit to active content.翻转和倒带之间的区别在于翻转将位置设置为 0 并将限制设置为活动内容。 Method rewind just sets the position to 0.方法 rewind 只是将位置设置为 0。

For more information http://www.zoftino.com/java-nio-tutorial更多信息http://www.zoftino.com/java-nio-tutorial

@user963241 To add more colour on @EJP's answer. @user963241 在@EJP 的回答中添加更多颜色。

flip() makes it ready for write() (or for get()) flip() 使其为 write() (或 get() )做好准备

get() Example; get() 示例;

You might want to read data from the buffer ( assuming that you had initially stored it in there )and use it for something else such as converting to a string and manipulate it for further use.您可能希望从缓冲区读取数据(假设您最初将其存储在那里)并将其用于其他用途,例如转换为字符串并对其进行操作以供进一步使用。

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() Example;写()示例; After you have read data from socket channel into the buffer you might want to write it back to socket channel - assuming that you want to implement something like a server that echos same message received from client.从套接字通道数据读入缓冲区后,您可能希望将其写回套接字通道 - 假设您想要实现类似服务器的东西,该服务器回显从客户端接收到的相同消息。

So you will read from channel to buffer and from buffer back to channel因此,您将从通道读取到缓冲区,然后从缓冲区读取回通道

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


  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM