Channels and buffers
Channel s and
Buffer s are the central objects in NIO, and are used for just about every I/O operation.
Channels are analogous to streams in the original I/O package. All data that goes anywhere (or comes from anywhere) must pass through a
Channel object. A
Buffer is essentially a container object. All data that is sent to a channel must first be placed in a buffer; likewise, any data that is read from a channel is read into a buffer.
In this section, you will learn about working with channels and buffers in NIO.
Buffer is an object, which holds some data, that is to be written to or that has just been read from. The addition of the
Buffer object in NIO marks one of the most significant differences between the new library and original I/O. In stream-oriented I/O, you wrote data directly to, and read data directly from,
In the NIO library, all data is handled with buffers. When data is read, it is read directly into a buffer. When data is written, it is written into a buffer. Anytime you access data in NIO, you are pulling it out of the buffer.
A buffer is essentially an array. Generally, it is an array of bytes, but other kinds of arrays can be used. But a buffer is more than just an array. A buffer provides structured access to data and also keeps track of the system's read/write processes.
The most commonly used kind of buffer is the
get/set operations (that is, the getting and setting of bytes) on its underlying byte array.
ByteBuffer is not the only type of buffer in NIO. In fact, there is a buffer type for each of the primitive Java types:
Each of the
Buffer classes is an instance of the
Buffer interface. With the exception of
each one has the exact same operations, differing only in the type of data it deals with. Because
ByteBuffer is used for most standard I/O operations it has all of the shared buffer operations as well as some that are unique.
You may want to take a moment now to run the UseFloatBuffer.java, which contains an example of typed buffers in action.
Channel is an object from which you can read data and to which you can write data. Comparing NIO with original I/O, a channel is like a stream.
As previously mentioned, all data is handled through
Buffer objects. You never write a byte directly to a channel; instead you write to a buffer containing one or more bytes. Likewise, you don't read a byte directly from a channel; you read from a channel into a buffer, and then get the bytes from the buffer.
Channels differ from streams in that they are bi-directional. Whereas streams only go in one direction (a stream must be a subclass of either
OutputStream ), a
Channel can be opened for reading, for writing, or for both.
Because they are bi-directional, channels better reflect the reality of the underlying operating system than streams do. In the UNIX model in particular, the underlying operating system channels are bi-directional.