[英]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.