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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16461284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:01:06  来源:igfitidea点击:

difference between bytebuffer.flip() and bytebuffer.rewind()

javaionio

提问by Rollerball

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. EDIT:I found the solution in thislink, it's very well explained and detailed for a thorough understanding of the buffer and channel classes' use.

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

回答by lxy

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 flipset the limitto the position, while rewindnot. 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:

所以区别在于将flip设置limitposition,而rewind不是。假设你分配了一个8字节的缓冲区,你已经用4个字节填充了缓冲区,那么位置设置为3,如下所示:

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

So rewindjust used limit has set appropriately.

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

回答by user207421

They're not equivalent at all.

它们根本不等价。

A ByteBufferis normally ready for read()(or for put()).

AByteBuffer通常准备好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()使其准备read()/put()再次后write()(或get())。

回答by sofia

The rewind( ) method is similar to flip( ) but does not affect the limit. 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. 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.

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

回答by Gonen I

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. If you try to read any more than that, it will throw an exception.

因此,使用 flip 时,如果您正在写入 ( put ) ,则读取限制 ( get ) 将成为您写入的最后一个元素的位置。如果您尝试阅读更多内容,它将引发异常。

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

回答by Arnav Rao

Buffer has position, limit and capacity properties. You can allocate space for n number of elements while creating a buffer. Here n is the capacity. After buffer is allocated, position is set to 0 and limit is set to capacity.

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

If you filled the buffer with n-x number of elements, position will be set to n-x. Buffer will have empty elements after n-x.

如果用 nx 个元素填充缓冲区,则位置将设置为 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 n-x. Flip sets the limit and position properties like described above.

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

Difference between flip and rewind is that flip sets the position to 0 and sets limit to active content. Method rewind just sets the position to 0.

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

For more information http://www.zoftino.com/java-nio-tutorial

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

回答by crakama

@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 bufferyou 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


  }