Input / Output - NIO

NIO : news of JDK 1.4

The new input/output (NIO) library was introduced with JDK 1.4. Picking up where original I/O leaves off, NIO provides high-speed, block-oriented I/O in standard Java code. By defining classes to hold data, and by processing that data in blocks, NIO takes advantage of low-level optimizations in a way that the original I/O package could not, without using native code.

Streams versus blocks

The most important distinction between the original I/O library (found in*) and NIO has to do with how data is packaged and transmitted. As previously mentioned, original I/O deals with data in streams, whereas NIO deals with data in blocks.
  1. stream-oriented I/O : system deals with data one byte at a time. An input stream
produces one byte of data, and an output stream consumes one byte of data. It is very easy to create filters for streamed data. It is also relatively simply to chain several filters together so that each one does its part in what amounts to a single, sophisticated processing mechanism. On the flip side, stream-oriented I/O is often rather slow.
  1. block-oriented I/O : system deals with data in blocks. Each operation produces or
consumes a block of data in one step. Processing data by the block can be much faster than processing it by the (streamed) byte. But block-oriented I/O lacks some of the elegance and simplicity of stream-oriented I/O.
Presented by developerWorks, your source for great tutorials

Channels and buffers

Channels and Buffers 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.
List of available buffers for primitives (ByteBuffer, CharBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer, DoubleBuffer).
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 InputStream or OutputStream), a Channel can be opened for reading, for writing, or for both.
Three values can be used to specify the state of a buffer at any given moment in time:
  • position
  • limit
  • capacity

In practice

Reading and writing are the fundamental processes of I/O. Reading from a channel is simple: we simply create a buffer and then ask a channel to read data into it. Writing is also fairly simply: we create a buffer, fill it with data, and then ask a channel to write from it.

Reading a file : -getting the Channel from FileInputStream -creating the Buffer -reading from the Channel into the Buffer

FileInputStream fin = new FileInputStream("test.txt"); FileChannel fc = fin.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024);;

Writing a file :

FileOutputStream fout = new FileOutputStream("test.txt"); FileChannel fc = fout.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); String message = "the content of the file..."; for (int i=0; i<message.length; ++i) { buffer.put(message[i]); } buffer.flip(); fc.write(buffer);

Copy file :

FileInputStream fin = new FileInputStream(infile); FileOutputStream fout = new FileOutputStream(outfile); FileChannel fcin = fin.getChannel(); FileChannel fcout = fout.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); while (true) { buffer.clear(); int r =; if (r==-1) { break; } buffer.flip(); fcout.write(buffer); }

Methods of Buffers :

  • It sets the limit to the current position.
  • It sets the position to 0.
  • It sets the limit to match the capacity.
  • It sets the position to 0.

Create an Buffer

ByteBuffer buffer = ByteBuffer.allocate(1024);
byte array[] = new byte[1024]; ByteBuffer buffer = ByteBuffer.wrap(array);
//slice is a sub-buffer of buffer. However, slice and buffer share the same //underlying data array, as we'll see in the next section.
buffer.position(3); buffer.limit(7); ByteBuffer slice = buffer.slice();

Article extrait du site