• notice
  • Congratulations on the launch of the Sought Tech site

What is the difference between NIO and NIO.2?

1. Introduction

In this tutorial, we will introduce Java IO features and how they have changed in different Java versions. First, we'll cover the initial Java release. java.ioNext, we'll cover java.niothe java.nio package that was introduced in Java 1.4. Finally, we'll introduce java.nio.filepackages, commonly referred to as NIO.2 packages.

2. Java NIO package

The first Java version java.iowas released with the package, introducing a Fileclasses to access the file system. FileClasses represent files and directories and provide limited operations on the file system. Files can be created and deleted, checked for their existence, checked for read/write access, etc.

It also has some disadvantages:

  • Missing copy method - to copy a file we need to create two Fileinstances and use a buffer to read one and write to the other File.

  • Error handling errors - some methods return booleanas an indicator of the success or failure of the operation.

  • A limited set of file properties - name, path, read/write permissions, available memory size, etc.

  • Blocking API - Our thread is blocked until the IO operation completes.

To read a file, we need an FileInputStreaminstance to read bytes from the file:

public void readFromFileUsingFileIO() throws Exception {
File file = new File("src/test/resources/nio-vs-nio2.txt");
FileInputStream in = new FileInputStream(file);
StringBuilder content = new StringBuilder(); int data = in.read(); while (data != -1) {
content.append((char) data);
data = in.read();
assertThat(content.toString()).isEqualTo("Hello from file!");

Next, Java 1.4 introduced the java.nionon-blocking IO API (nio stands for New IO) bundled in the package. NIO was introduced to overcome java.iopackage limitations. This package introduces three core classes: ChannelBufferand Selector.

2.1 Channel

Java NIO Channelis a class that allows us to read and write buffers . ChannelClasses are similar Streams(here we're talking about IO Streams, not Java 1.8 Streams), but with a few differences. Channelare bidirectional, and Streamsusually unidirectional, they can be read and written asynchronously.

ChannelThe class has several implementations, including FileChannelfor filesystem read/write, DatagramChannelfor read/write over the network using UDP, and SocketChannelfor read/write over the network using TCP.

2.2 Buffer

A buffer is a piece of memory from which we can read or write data . A NIO Bufferobject wraps a block of memory. BufferClasses provide a set of functions that work with blocks of memory. To work with Bufferobjects, we need to understand Bufferthe three main properties of classes: capacity, location, and constraints.

  • The capacity defines the size of the memory block. When we write data to the buffer, we can only write to a limited length. When the buffer is full, we need to read the data or clear the data.

  • The location is the starting point from which we write data. An empty buffer starts at 0 capacity – 1. Also, when we read the data, we start with the position value.

  • Limits mean how we can write and read from the buffer.

BufferThere are many variants of classes. One per primitive Java type, excluding Booleantypes and MappedByteBuffer.

To use buffers, we need to know some important methods:

  • allocate(int value) –We use this method to create a buffer of a specific size.

  • flip() - This method is used to switch from write mode to read mode

  • clear() –Method to clear buffer contents

  • compact() –A way to only clear what we've already read

  • rewind() –The position is reset to 0 so that we can re-read the data in the buffer

Using the concepts described earlier, let's use the Channeland Bufferclasses to read content from a file:

public void readFromFileUsingFileChannel() throws Exception {
RandomAccessFile file = new RandomAccessFile("src/test/resources/nio-vs-nio2.txt", "r");
FileChannel channel = file.getChannel();
StringBuilder content = new StringBuilder();
ByteBuffer buffer = ByteBuffer.allocate(256); int bytesRead = channel.read(buffer); while (bytesRead != -1) {
while (buffer.hasRemaining()) {
content.append((char) buffer.get());
bytesRead = channel.read(buffer);
assertThat(content.toString()).isEqualTo("Hello from file!");

After initializing all required objects, we read from the channel to the buffer. Next, in the while loop, we use the flip()method to mark the buffer to read and read one byte at a time and append it to our result. Finally, we clear the data and read another batch.

2.3. Selector

Java NIO Selector allows us to manage multiple channels with one thread. To monitor multiple channels with a selector object, each channel instance must be in non-blocking mode and we must register it. After the channel is registered, we get an SelectionKeyobject representing the connection between the channel and the selector. When we have multiple channels connected to a selector, we can use select()methods to check how many channels are available. After calling select()the method, we can use the selectedKeys()method to get all prepared channels.

2.4. Disadvantages of NIO package

java.nioThe changes introduced by the package are more related to the underlying data IO. While they allow a non-blocking API, other areas remain problematic:

  • Limited support for symbolic links

  • Limited support for file attribute access

  • Lack of better file system management tools

3. Java NIO.2 package

Java 1.7 introduced new java.nio.filepackages, also known as NIO.2 packages. java.nioAsync methods for non-blocking IO not supported in the package. The most important changes are related to advanced file operations. They are added with Files, Path,and Pathsclasses. The most notable low-level changes are the addition of AsynchroniousFileChanneland AsyncroniousSocketChannel.

PathAn object represents a hierarchical sequence of directory and file names separated by a delimiter . The root component is on the far left, and the file is on the right. This class provides utility methods such as getFileName()getParent()etc. PathThe class also provides resolveand relativizemethods to help build paths between different files. The Paths class is a set of static utility methods that receive Stringor URIcreate Pathinstances.

FilesClasses provide utility methods for using the previously described Pathclasses and manipulating files, directories, and symbolic links. It also provides a readAttributes()way to read many file properties using methods.

Finally, let's see how NIO.2 compares to previous IO versions when reading files:

public void readFromFileUsingNIO2() throws Exception {
List<String> strings = Files.readAllLines(Paths.get("src/test/resources/nio-vs-nio2.txt"));
assertThat(strings.get(0)).isEqualTo("Hello from file!");

4 Conclusion

In this article, we covered the basics of java.nioand java.nio.filepackages. As we can see, NIO.2 is not a new version of the NIO package. The NIO package introduced a low-level API for non-blocking IO, while NIO.2 introduced better file management. The two packages are not synonymous but complement each other.


Technical otaku

Sought technology together

Related Topic


Leave a Reply