簡體   English   中英

bytebuffer.flip() 和 bytebuffer.rewind() 的區別

[英]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設置了positionlimit ,而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。

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

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM