[英]difference between bytebuffer.flip() and bytebuffer.rewind()
我知道 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());
你能给我提供一个真实的例子,说明这两种方法的区别真的很重要吗? 提前致谢。
从源代码来看,它们非常相似。 您可以看到以下内容:
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
public final Buffer rewind() {
position = 0;
mark = -1;
return this;
}
所以区别在于flip
设置了position
的limit
,而rewind
没有。 假设你分配了一个8字节的缓冲区,你已经用4个字节填充了缓冲区,那么位置设置为3,如下所示:
[ 1 1 1 1 0 0 0 0]
| |
flip limit |
rewind limit
所以rewind
刚刚使用的限制已适当设置。
它们根本不等价。
ByteBuffer
通常准备好用于read()
(或用于put()
)。
flip()
使其为write()
(或get()
)做好准备。
rewind()
和compact()
和clear()
在write()
(或get()
)之后再次准备好read()/put()
) 。
rewind() 方法类似于flip(),但不影响限制。 它只将位置重新设置为 0。您可以使用 rewind() 返回并重新读取已经翻转的缓冲区中的数据。 一种常见的情况是:在您使用 flip() 之后,您从缓冲区读取数据,您想重新读取数据,此方法将起作用。
这是一个示例,其中两者将产生不同的结果。 正如你所说,两者都将位置设置为0,两者之间的区别在于翻转将限制设置为前一个位置。
因此,使用 flip 时,如果您正在写入 ( 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
缓冲区具有位置、限制和容量属性。 您可以在创建缓冲区时为 n 个元素分配空间。 这里 n 是容量。 分配缓冲区后,位置设置为 0,限制设置为容量。
如果用 nx 个元素填充缓冲区,则位置将设置为 nx。 缓冲区将在 nx 之后有空元素。
如果此时您想排空缓冲区并且只想要非空值,则需要将当前位置的限制和位置设置为零。 使用 hasRemaining(),您可以获得元素直到 nx。 翻转设置限制和位置属性,如上所述。
翻转和倒带之间的区别在于翻转将位置设置为 0 并将限制设置为活动内容。 方法 rewind 只是将位置设置为 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;
}
写()示例; 从套接字通道将数据读入缓冲区后,您可能希望将其写回套接字通道 - 假设您想要实现类似服务器的东西,该服务器回显从客户端接收到的相同消息。
因此,您将从通道读取到缓冲区,然后从缓冲区读取回通道
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.