简体   繁体   中英

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

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.

In the following code, either I use rewind() or flip() i get the same result.

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.

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 flip set the limit to the position , while rewind not. 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:

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

So rewind just used limit has set appropriately.

They're not equivalent at all.

A ByteBuffer is normally ready for read() (or for put() ).

flip() makes it ready for write() (or for get() ).

rewind() and compact() and clear() make it ready for read()/put() again after write() (or get() ).

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.

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.

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.

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

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.

If you filled the buffer with nx number of elements, position will be set to nx. Buffer will have empty elements after 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 nx. Flip sets the limit and position properties like described above.

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.

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

@user963241 To add more colour on @EJP's answer.

flip() makes it ready for write() (or for get())

get() Example;

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 buffer you 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


  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM