What is the purpose of ByteBuffer's flip method? (And why is it called "flip"?)

61,144

Solution 1

One fairly common use case for the ByteBuffer is to construct some data structure piece-by-piece and then write that whole structure to disk. flip is used to flip the ByteBuffer from "reading from I/O" (putting) to "writing to I/O" (getting): after a sequence of puts is used to fill the ByteBuffer, flip will set the limit of the buffer to the current position and reset the position to zero. This has the effect of making a future get or write from the buffer write all of what was put into the buffer and no more.

After finishing the put, you might want to reuse the ByteBuffer to construct another data structure. To "unflip" it, call clear. This resets the limit to the capacity (making all of the buffer usable), and the position to 0.

So, a typical usage scenario:

ByteBuffer b = new ByteBuffer(1024);
for(int i=0; i<N; i++) {
    b.clear();
    b.put(header[i]);
    b.put(data[i]);
    b.flip();
    out.write(b);
}

Solution 2

Flip assigns the current position value to the limit property and sets the position property to 0. Flip is useful to drain only active elements from a buffer.

For example, below program prints "hello" instead of empty elements of the buffer. Method calls limit and position can be replaced with flip.

CharBuffer cbuff = CharBuffer.allocate(40);
cbuff.put("hello"); 
// These two lines below are what flip does
cbuff.limit(cbuff.position());
cbuff.position(0);
    
while(cbuff.hasRemaining()) {
    System.out.println(cbuff.get());
}

See http://www.zoftino.com/java-nio-tutorial for more information on buffers and channels.

Solution 3

flip() method makes a buffer ready for a new sequence of channel-write or relative get operations: It sets the limit to the current position and then sets the position to zero.

Buffer keeps track of the data written into it. Post writing, flip() method is called to switch from writing to reading mode.

Solution 4

A buffer has a fixed capacity; it maintains 2 pointers: start and end. get() returns the byte at the start position and increments start. put() puts the byte at the end position and increments end. No flip()!

Share:
61,144

Related videos on Youtube

Suzan Cioc
Author by

Suzan Cioc

Not to be offended

Updated on May 03, 2022

Comments

  • Suzan Cioc
    Suzan Cioc about 2 years

    Why does ByteBuffer's flip() method called "flip"? What is "flipped" here? According to apidoc, two successive flips won't restore original state, and multiple flips will probably tend limit() to become zero.

    Can I "unflip" somehow to reuse bytes went out of a limit?

    Can I concatenate tail to be flipped with some other data?

    • Brian Roach
      Brian Roach over 11 years
      It "flips" the buffer from read to write (and vice versa). thushw.blogspot.com/2009/10/…
    • nneonneo
      nneonneo over 11 years
      @BrianRoach: It flips from read to write but is not as useful for write to read unless you are writing fixed-size structures. For flipping to write to read, use reset instead.
    • Admin
      Admin over 11 years
      Remember to ask "objective" questions; or, at least, make the predominant question seem objective :D
    • Brian Roach
      Brian Roach over 11 years
      @nneonneo - It was kinda non-question, wasn't really going to spend much time on explaining the details, hence just a comment and a link.
  • nneonneo
    nneonneo over 11 years
    A WritableByteChannel, such as FileChannel or SocketChannel.
  • Stephen C
    Stephen C over 11 years
    Or anything else that has a write(ByteBuffer) method. (It is not really relevant what its type is ...)
  • nneonneo
    nneonneo over 11 years
    [[citation needed]] (I haven't heard these complaints about ByteBuffer). Also, the docs say there's only a "current position", not a "start" and "end".
  • irreputable
    irreputable over 11 years
    I have heard, you can take my word for it.
  • nneonneo
    nneonneo over 11 years
    So, what are the complaints? If you have some personal grievance that's OK too, but it does not do to just say "X API sucks, people said so".
  • nneonneo
    nneonneo over 11 years
    Posting that link is literally all you had to do in the first place. I never accused you of lying, I merely asked you to elaborate on the source and the nature of the complaints.
  • irreputable
    irreputable over 11 years
    this is just a place where people offer their help voluntarily, with the proper amount of effort they choose to. I do not need to expand each answer into a well researched academic paper.
  • arunmoezhi
    arunmoezhi about 11 years
    and this is also a place where people will not take someone's word unless it sounds credible.
  • Kelvin Ng
    Kelvin Ng over 10 years
    It should Buffer.clear which reset limit to capacity and position to 0. Buffer.reset reset only position to mark.
  • nneonneo
    nneonneo over 10 years
    @KelvinNg: You're right; I've amended the answer to reflect this. Thanks for the nice catch!
  • Gurgeh
    Gurgeh over 10 years
    You don't even need to give sources. It is blatantly obvious that ByteBuffer is ill designed. flip does not fill a purpose, it just introduces a source of bugs when you forget to flip. If they felt an uncontrollable urge to put it in, at least make flipped and unflipped ByteBuffers different classes, so the type system can catch the bugs.
  • stu
    stu over 10 years
    I respect people who offer criticism of standards despite the entrenchment of that standard. +1 +1 +1.
  • sawyer seguin
    sawyer seguin about 9 years
    In some scenarios (you have "unwritten" bytes left in the buffer, if for example the consumer can only consume 4 bytes at once) you may also want to use compact() which moves them to the beginning of the buffer so that you can continue reading bytes into the buffer after them.
  • Prashant
    Prashant over 7 years
    @AdamHughes second loop iteration reuses the cleared buffer. Having the clear at the end of the loop is also possible (but still has one clear call too many)
  • JoshDM
    JoshDM over 7 years
    flip sounds like the buffer direction is reversed. They need a verb to represent changing mode; switch is a keyword, so it's invalid, and shift has a whole other meaning in a bit-based context. swap or change are better choices than flip.
  • user207421
    user207421 about 7 years
    There is nothing here that answers the question.
  • user963241
    user963241 about 7 years
    @nneonneo: How does "reading" means (putting) and "writing" means (getting)? E.g. when we use put you write data into buffer.
  • nneonneo
    nneonneo about 7 years
    @user963241: read from I/O into buffer, write from buffer into I/O.
  • Willwsharp
    Willwsharp over 5 years
    This does not answer the question at all.
  • user207421
    user207421 over 4 years
    @KelvinNg Mark and reset are for InputStreams, not buffers.
  • Kelvin Ng
    Kelvin Ng over 4 years
    @user207421 OP fixed the bug in his code snippet at revision 2 stackoverflow.com/posts/14793037/revisions#
  • John
    John almost 4 years
    Thank you for the link to the very extensive coverage! It's so great when sources are included. The java API docs seemed to use the word 'flip' without explanation, as if it were a common computer science term, but obviously a few people (including me) haven't found that to be the case.