Section 3

Section 3

Java IO - New I/O

Learning Objectives: In this lesson, we will demonstrate how to work with Java IO Stream classes. By the end of the lesson, learners will be able to:

  • Describe Java New I/O (NIO).

  • Explain the core components of New I/O (NIO).

  • Demonstrate how to read and write data in a file using Java New I/O (NIO).

Table of Contents

  • Topic 1: Overview of Java New I/O.

  • Topic 2: Problem with Traditional Java IO Packages.

  • Topic 3: Core Components of Java NIO.

  • Topic 3a: Overview of Channels and Buffers.

  • Topic 3b: Overview of Selectors.

  • Topic 3c: Overview of Non-blocking I/O.

  • Topic 4: Java NIO Packages.

  • Topic 5: FileChannel Class Implementation.

  • Topic 6: Reading Data from a Buffer.

  • Topic 7: The flip() Method.

Topic 1: Overview of Java New I/O

Java has provided a second I/O system called New I/O (NIO).

  • It supports a buffer-oriented, channel-based approach for I/O operations.

  • NIO was developed to allow Java programmers to implement high-speed I/O without using the custom native code.

Topic 2: Problem with Traditional Java IO Packages

  • Java NIO channels are similar to streams but with a few differences. You can both read and write to a channel, but Streams are typically one-way (read or write).

  • A stream-oriented I/O system deals with data one or more bytes at a time. An input stream produces one byte of data, and an output stream consumes one byte of data. The important thing is that bytes are not cached anywhere. Furthermore, we cannot move back and forth in the data in a stream.

  • If we need to move back and forth in the data read from a stream, we must cache it in a buffer first.

  • Java NIO's buffer-oriented approach is slightly different. Data is read into a buffer from which it is later processed. You can move back and forth in the buffer as you need to. This gives you a bit more flexibility during processing. However, you also need to check if the buffer contains all of the data you need in order to fully process it. Further, you need to make sure that when reading more data into the buffer, you do not overwrite data in the buffer you have not yet processed.

  • The java.nio.file.Path does everything java.io.File can, but generally in a better way.

Topic 3: Core Components of Java NIO

The NIO package is based on core components used in the reading and writing operation:

  1. Channels and Buffers.

  2. Selectors (Thread).

  3. Non-blocking I/O.

Topic 3a: Overview of Channels and Buffers

  • In standard I/O API, the character streams and byte streams are used, but in NIO, we work with channels and buffers. Data is always written from a buffer to a channel, and read from a channel to a buffer.

  • A channel is like a stream. It represents a connection between a data source and a destination.

  • A buffer is an object, which holds some data that is to be written to or that has just been read from.

  • In Java NIO, the primary channels used are:

    • The FileChannel reads data from and to files.

    • The DatagramChannel can read and write data over the network via UDP(User Datagram Protocol ).

    • The SocketChannel can read and write data over the network via TCP.

    • The ServerSocketChannel allows you to listen for incoming TCP connections, similar to what a web server does. For each incoming connection, a SocketChannel is created.

  • In Java NIO, ByteBuffer is not the only type of buffer. In fact, there is a buffer data type for each of the primitive Java types.

Topic 3b: Overview of Selectors

  • Java NIO provides the concept of "selectors." It is an object that can be used for monitoring the multiple channels for events such as data arrived, connection opened, etc. Therefore, a single thread can monitor the multiple channels for data.

Topic 3c: Overview of Non-blocking I/O

  • Java NIO provides the feature of Non-blocking I/O.

  • Non-blocking IO does not wait for the data to be read or written before returning. Java NIO non-blocking mode allows the thread to request writing data to a channel, but not wait for it to be fully written. The thread is allowed to go on and do something else in the meantime.

Topic 4: Java NIO Packages

Java NIO provides a new I/O model based on channels, buffers, and selectors. So, these modules are considered as the core of the API. The following table illustrates the list of Java.nio packages for an NIO system and why they are used:

PackagePurpose

java.nio

The top-level package for NIO system. The various types of buffers are encapsulated by this NIO system.

java.nio.charset

Encapsulates the character sets and also supports the encoder and decoder operations that convert characters to bytes and bytes to characters, respectively.

java.nio.charset.spi

Supports the service provider for character sets.

java.nio.channels

Supports the channels, which are essentially open the I/O connections.

java.nio.channels.spi

Supports the service providers for channels.

java.nio.file

Provides the support for files.

java.nio.file.spi

Supports the service providers for file system.

java.nio.file.attribute

Provides the support for file attributes.

Topic 5: FileChannel Class Implementation

  • The file channel is used for reading the data from the files. It's object can be created only by calling the getChannel() method. But before you use a FileChannel, you must open it. We cannot create a FileChannel object directly.

  • Reading from a file involves three steps:

    1. Obtain a FileChannel via an InputStream, OutputStream, File class, Pathclass, etc.

    2. Declare and initialize the Buffer size.

    3. Read from the Channel into the Buffer.

Topic 6: Reading Data from a Buffer

  • Once we read data from the Channel into the Buffer, we can access or read data from the Buffer.

  • We can use two methods for reading the data from a Buffer:

    • Read the data from a Buffer by using the get() method of buffer class. This method is used to read data from a buffer and read one byte at a time from the buffer.

    • Read the data from a Buffer into a Channel by using the write() method of FileChannel class.

Topic 7: The flip() Method

The flip() method switches the mode of the buffer from writing mode to reading mode. It also sets the position back to 0 and sets the limit to where the position was at the time of writing.

In this example, we will demonstrate how to read data from a text file, how the channel is created, and how the buffer is declared. Then we will demonstrate how to read data from the buffer and print the content to the console using NIO classes and methods.

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class ChannelDemoTwo {
	public static void main(String args[]) throws IOException {
		String fname = "C:/Downloads/testingFile.txt";
		FileInputStream file = new FileInputStream(fname);
		FileChannel fileChannel = file.getChannel();
		long filesize = fileChannel.size();
		ByteBuffer byteBuffer = ByteBuffer.allocate((int) filesize);
		while (fileChannel.read(byteBuffer) > 0) {
			while (byteBuffer.hasRemaining()) {
				System.out.print((char) byteBuffer.get());
			}
		}
		file.close();
		fileChannel.close();
	}
}

Hands-On Lab - NIO

Find the lab GLAB - 303.13.2 - NIO on Canvas under the Assignment section.

Knowledge Check

  • State the difference between Standard IO and NIO.

  • How do channels differ from streams in Java?

  • What is a selector?

  • What is a buffer?

Summary

  • The Java program reads from or writes to a stream — one byte at a time.

  • The Java NIO package provides one more utility API named Files, which is basically used for manipulating files and directories using its static methods — most of which work on Path objects.

  • Java NIO is a buffer-oriented approach.

  • A Buffer is an object, which holds some data that is to be written to, or that has just been read from. Buffers are defined inside java.nio package. It defines the core functionality, which is common to all buffers: limit, capacity, and current position.

  • NIO transports the time-consuming I/O operations to the buffers, allowing threads to move to other processes; and thus, speeds up the system.

  • Components of NIO in Java:

    • Channels.

    • Buffers.

    • Selectors.

References

Questions?

Last updated