Introduction
Java has provided a second I/O system called NIO (Non-blocking I/O). Java NIO provides a different way of working with I/O than the standard I/O APIs. It is an alternate I/O API for Java (from Java 1.4).
Java NIO API is a collection of Java programming language APIs that offer features for intensive I/O operations. It was introduced with the J2SE 1.4 release of Java by Sun Microsystems to complement an existing standard I/O. NIO was developed under the Java Community Process as JSR 51. An extension to NIO that offers a new file system API, called NIO.2, was released with Java SE 7 (“Dolphin”).
The Java NIO APIs are provided in the java.nio package and its sub-packages.
Features of NIO in Java
The APIs of NIO were designed to provide access to the low-level I/O operations of modern operating systems. Although the APIs are themselves relatively high-level, the intent is to facilitate an implementation that can directly use the most efficient operations of the underlying platform.
- A file interface that supports locks and memory mapping of files up to Integer.MAX_VALUE bytes (2 GB)
- Buffers for data of primitive types
- Character set encoders and decoders
- A file interface that supports locks and memory mapping
- A multiplexed, non-blocking I/O facility for writing scalable servers
- A pattern-matching facility based on Perl-style regular expressions (in package java.util.regex)
Also, NIO API offers selectors that introduce the functionality of listening to multiple channels for IO events in an asynchronous or non-blocking way. In NIO, the most time-consuming I/O activities include filling and draining of buffers to the operating system, which increases in speed.
Componentes of NIO in Java
- Channels
- Buffers
- Selectors
Java NIO has more classes and components than these, but the Channel, Buffer, and Selector form the core of the API, in my opinion. The rest of the components, like Pipe and FileLock, are merely utility classes to be used in conjunction with the three core components.
What is the channel in NIO?
All IO (Input / Output) starts with a channel in NIO in Java. Data can be read into a Buffer from the channel. Java NIO channels are similar to streams. There are a few points which show the similarities between channels and streams
- Both can read and write to channels, but streams are typically one-way (read or write).
- Channels can be read and written asynchronously.
- Channels always read to and write from a Buffer.
Channels List
Here are some important channel implementations in Java NIO.
- FileChannel- reads the data from and to the files.
- DatagramChannel- reads and writes data over the network via UDP.
- SocketChannel- reads and writes data over the network via TCP.
- ServerSocketChannel- allows listening for incoming TCP connections, as a web server does. For each incoming connection, a SocketChannel is created.
The complete program of the Channel in NIO is listed below.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
public class Main {
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
// Path Of The Input Text File
FileInputStream input = new FileInputStream ("sampleInput.txt");
ReadableByteChannel source = input.getChannel();
// Path Of The Output Text File
FileOutputStream output = new FileOutputStream ("sampleOutput.txt");
WritableByteChannel destination = output.getChannel();
copyData(source, destination);
System.out.println("! File Successfully Copied From Source To Destination !");
} Here are some important channel implementations in Java NIO.
private static void copyData(ReadableByteChannel source, WritableByteChannel destination) throws IOException {
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
while (source.read(buffer) != -1) {
// The Buffer Is Used To Be Drained
buffer.flip();
// Make Sure That The Buffer Was Fully Drained
while (buffer.hasRemaining()) {
destination.write(buffer);
}
// Now The Buffer Is Empty!
buffer.clear();
}
}
}
Note. Here, first, we have to create 2 ".txt" files named "sampleInput.txt" and "sampleOutput.txt" and then a ".java" file named "Main.java" and compile our following program. If the data of the "sampleInput.txt" file is copied into the other file, the "sampleOutput.txt", it will return the output as shown below.
What is the Buffer in NIO?
Java NIO Buffers are used when interacting with NIO channels. Data is written from the buffers into the channels. A buffer is essentially a block of memory into which you can write data, which you can then later read again.
This memory block is wrapped in an NIO Buffer object, which provides a set of methods that make it easier to work with the memory block.
Use of Buffer
Using a Buffer to read and write data typically follows these 4 steps.
- Write data into the Buffer.
- Call buffer.flip()
- Read data out of the Buffer
- Call buffer.clear() or buffer.compact()
When we write the data into the buffer, it keeps track of how much data has been written. When written data is complete, we need to switch the buffer from writing to reading mode. The flip() method is used for this purpose. In reading mode, we only can read the data from the buffer.
Once we have read the data, we clear the buffer to make it ready for writing again. clear() method or compact() method is used to clear the buffer.
- The clear() method clears the whole buffer.
- The compact() method only clears the data which you have already read.
If there is any unread data available in the buffer, it will move to the beginning of the buffer, and data will now be written into the buffer after the unread data.
Some primary parameters that define NIO buffer in Java are listed below-
- Capacity: Maximum amount of data that can be stored in the buffer. Its capacity can not be altered. Once the buffer is full it should be clear before writing in it.
- Limit: Limit as the mode of the buffer. Write mode of the buffer is a limit is equal to the maximum capacity of data that could be written in the buffer. On the other side, the read mode limit of the buffer is how much data can be read from the buffer.
- Position: It is the index of the next element to be read from the buffer and write into the buffer by the get() and put() method.

Join the conversation! Your thoughts help the community grow.