web-dev-qa-db-ja.com

bytebuffer.flip()と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());

これら2つの方法の違いが本当に重要な実際の例を教えてください。前もって感謝します。 編集:解決策は this リンクで見つかりました。バッファとチャネルを完全に理解するために、非常によく説明され、詳細に説明されています。クラスの使用。

22
Rollerball

ソースコードから、それらは非常に似ています。あなたは以下を見ることができます:

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

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

したがって、違いはfliplimitpositionに設定するのに対し、rewindは設定しないことです。 8バイトのバッファーを割り当て、バッファーを4バイトで満たした後、位置が3に設定されたとすると、次のように表示されます。

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

したがって、rewind使用されたばかりの制限が適切に設定されています。

15
lxy

それらはまったく同等ではありません。

ByteBufferは通常、read()(またはput())の準備ができています。

flip()は、write()(またはget())の準備をします。

rewind()compact()clear()は、read()/put()(またはwrite())の後に再びget()の準備をします。

10
user207421

Rewind()メソッドはflip()に似ていますが、制限には影響しません。位置を0に戻すだけです。rewind()を使用して、すでに反転されているバッファーに戻ってデータを再読み取りできます。一般的な状況は次のとおりです。flip()を使用した後、バッファーからデータを読み取り、データを再読み取りする場合、このメソッドは機能します。

3
sofia

バッファには、位置、制限、および容量のプロパティがあります。バッファの作成中に、n個の要素にスペースを割り当てることができます。ここで、nは容量です。バッファが割り当てられた後、位置は0に設定され、制限は容量に設定されます。

バッファにn-x個の要素を入力した場合、位置はn-xに設定されます。 n-xの後、バッファには空の要素があります。

この時点でバッファを空にし、空でない値のみが必要な場合は、現在の位置に制限を設定し、位置をゼロに設定する必要があります。 hasRemaining()を使用すると、n-xまで要素を取得できます。 Flipは、上記のように制限と位置のプロパティを設定します。

フリップと巻き戻しの違いは、フリップは位置を0に設定し、制限をアクティブコンテンツに設定することです。メソッド巻き戻しは、位置を0に設定するだけです。

詳細については http://www.zoftino.com/Java-nio-tutorial

1
Arnav Rao

これは、2つが異なる結果を生成する例です。あなたが言ったように、両方とも位置を0に設定します、2つの違いは、フリップが制限を前の位置に設定することです。

したがって、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
1
Gonen I

@ 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;
}

write()の例;ソケットチャネルからデータを読み取った後バッファにソケットチャネルにデータを書き戻すことができます-のようなものを実装したいと仮定しますクライアントから受信した同じメッセージをエコーするサーバー。

したがって、チャネルからバッファへ、およびバッファからチャネルへと読み取ります。

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


  }
0
crakama