Computers have been my hobby since I was 12. Now I'm a freelance Java developer. Like many other developers I am working on various private projects. Some are open source components (Butterfly Components - DI container, web ui, persistence api, mock test api etc.). Some are the tutorials at tutorials.jenkov.com. Yet others are web projects. I hold a bachelor degree in computer science and a master degree in IT focused on P2P networks. Jakob has posted 35 posts at DZone. You can read more from them at their website. View Full User Profile

Java NIO - Question About Buffer Design

05.20.2010
| 5401 views |
  • submit to reddit

I am currently writing a tutorial on Java NIO, and I have just updated the text on Buffers. About the design of Buffers, I have question to the Java community, but let me first describe the Buffer mechanism it is about:

When you create a new Buffer, e.g. a ByteBuffer, it is in write mode. The Buffer has a limit saying how many bytes you can write into it, and a position of the next byte to write into.

When you are done writing data into a Buffer, you call flip(). The Buffer is now in read mode.

The limit property now tells how many bytes you can read from the Buffer (how many bytes were written), and the position now tells the next byte to read.

When you are done reading, you call clear() or compact(), which switches the Buffer back into write mode.

Why did the NIO designers choose to have this distinction between "write" and "read" mode, and thus
the meaning of "limit" and "position" ?

As I see it, it causes two problems:

1) A Buffer is always in either "read" or "write" mode. I cannot be in both modes at the same time.

2)  When you receive af Buffer as a parameter, how do you know if it's in read or write mode?

 In my opinion a much smarter design would have been to simply have a read position and a write position
instead of "position" and "limit". This way you could always both read and write from the Buffer.

Read, if the read position is less than write position.
Write, if write position is less than capacity of Buffer.

Does anyone have any deep insights into the NIO Buffer design?

- Jakob Jenkov

Published at DZone with permission of its author, Jakob Jenkov.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Matteo Battaglio replied on Thu, 2010/05/20 - 8:29am

I've been intensively using NIO buffers for more than a year now, and I can assure you that there isn't any read or write mode: you can always read or write from/to a Buffer; both read and write operations involve bytes between Buffer.position() and Buffer.limit().

Melv Ng replied on Thu, 2010/05/20 - 4:04pm

As you are saying yourself, there is no real read/write modes, only "read" and "write". There is only the concept of "read" and "write" modes, which comes down to how the buffer is used in some piece of code.

For using the same buffer data from multiple places, try use ByteBuffer.duplicate(). It allows you to create multiple access views on the same raw data.

 *edit*

Sorry, I didn't read your wish to have the read and write operate on the same "write position", which works as a limit for reads and pos for writes.

I don't know why the buffers are the way the are (designer tried to keep implementation simple?). My only guess is that they tried to follow how a stream works, which only tracks the current position. Oh, when I think of it, that might just be the reason. If a buffer wraps a native stream like data, like a file, you only got the current position(?)

But I can imagine your suggestion could make it easier for newcomers to use buffers.

BTW, cool tutorial :)

Jakob Jenkov replied on Thu, 2010/05/20 - 5:12pm in response to: Melv Ng

Thanks for the answer, and the comment :-)

 

You are right, there are no *explicit* read and write mode. Only how position and limit are interpreted / set in the two "modes". 

I just thought it would have been easier to have a read position and a write position, thus allowing reads and writes easily interleaved.

Jose Maria Arranz replied on Fri, 2010/05/21 - 1:43am

ByteBuffer is at the same time, a byte collection and an iterator... bad design (and it isn't thread safe).

Fortunately you have duplicate()

 

 

Jakob Jenkov replied on Fri, 2010/05/21 - 2:06am in response to: Jose Maria Arranz

> ByteBuffer is at the same time, a byte collection and an iterator... bad design

From an OO perspective I agree with you, but from a high performance IO perspective I think working as close to the source (the array / buffer of data) is desirable. 

In my eyes, "good design" depends on what you are trying to achieve with your design.

Jörg Buchberger replied on Fri, 2010/05/21 - 4:07am

Jakob,

no deep insights from myself, however I do know of someone who has ... Trustin Lee of Netty fame. The netty forums seem very welcoming: http://www.jboss.org/netty/community.html#nabble-f685700

Then probably the guys of the XNIO project ( http://www.jboss.org/xnio ) are very experienced as well.

Cheers.
Jörg

Jakob Jenkov replied on Sat, 2010/05/22 - 4:16am in response to: Jörg Buchberger

Thanks - of course... the Netty guys ought to know a lot :-)

Alex(JAlexoid) ... replied on Sun, 2010/05/23 - 6:31pm in response to: Jose Maria Arranz

and it isn't thread safe

If they had decided not to put in mutexes into it(witch would be sensible for a non-shared buffer), that would make more sense. But there should be people with more insights on this.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.