AsynchronousFileChannel in Java NIO
Java.nio package was introduced in the version java 1.4 edition. It allows us to deal with different channels concurrently because it supports concurrency and multi-threading. The asynchronous file channel API is responsible for the java NIO package and it is defined under the NIO channels package. In order to import the AsynchronousFileChannel API to our program follow the below syntax as follows:
Syntax:
import java.nio.channels.AsynchronousFileChannel
Asynchronous channels are safe for use by multiple concurrent threads because this channel enables file operations to execute asynchronously unlike synchronous I/O operations in which a thread enters into action and waits until the request is completed. This is the only difference between the asynchronousFileChannel and NIO’s FileChannel.
The request is first passed by the threads to the kernel of the operating system to get it done while the thread continues to another job. After the job of the kernel is done, it signals the thread, then the thread acknowledges the signal and interrupts the current job and processes the I/O job as needed in asynchronous channels.
Approaches:
There are two approaches for achieving concurrency and these are as listed below. We will see the above two approaches in detail with the examples.
- Future Object
- Completion Handler
Approach 1: Future Object
It returns a java.util.concurrent.Future object. There are two useful methods to retrieve information and these two methods are –
- get() method: It returns the status of the operation that is handled asynchronously on the basis of which further execution of other tasks could get decided.
- isDone() method: This method will check whether the task is completed or not.
Example
Java
// Java Program to Illustrate AsynchronousFileChannel Class // Via Future Object Approach // Importing package package com.java.nio; // Importing required classes from java.nio package import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousFileChannel; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; // Main class // FutureObjectExample public class GFG { // Method 1 // Main driver method public static void main(String[] args) throws Exception { // Calling the readFile() method that will run first readFile(); } // Method 2 // To read the file private static void readFile() throws IOException, InterruptedException, ExecutionException { // Path of the file String filePath = "C:/users/Sir/Desktop/fileCopy.txt" ; // First create the file and then specify its // correct path printFileContents(filePath); Path path = Paths.get(filePath); AsynchronousFileChannel channel = AsynchronousFileChannel.open( path, StandardOpenOption.READ); ByteBuffer buffer = ByteBuffer.allocate( 400 ); Future<Integer> result = channel.read(buffer, 0 ); // Checking whether the task is been completed or // not while (!result.isDone()) { System.out.println( "The process of reading file is in progress asynchronously." ); } // Print and display statements System.out.println( "Is the reading done? " + result.isDone()); System.out.println( "The number of bytes read from file is " + result.get()); buffer.flip(); System.out.print( "Buffer contents: " ); while (buffer.hasRemaining()) { System.out.print(( char )buffer.get()); } System.out.println( " " ); // Closing the channels using close() method buffer.clear(); channel.close(); } // Method 3 // To print the contents of the file private static void printFileContents(String path) throws IOException { FileReader fr = new FileReader(path); BufferedReader br = new BufferedReader(fr); String textRead = br.readLine(); System.out.println( "Content in the File: " ); while (textRead != null ) { // After reading all the text from the file it // print the number of bytes in the file. System.out.println( " " + textRead); textRead = br.readLine(); } // Closing the channels // Closing the fr object fr.close(); // Closing the br object br.close(); } } |
Output:
Approach 2: Completion handler
For this approach, we are going to use the CompletionHandler interface and It consists of two useful methods that we are going to override. In this, a completion handler is created for consuming the result of an asynchronous I/O operation as once a task is completed then only the handler has functions that are executed.
These two methods are as follows:
- completed() method: This method is invoked when the I/O operation completes successfully.
- failed() method: This method is invoked if the I/O operations fail.
Example
Java
// Java Program to Illustrate AsynchronousFileChannel Class // Via Completion handler Approach // Importing required classes from respective packages package com.java.nio; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousFileChannel; import java.nio.channels.CompletionHandler; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; // Main class // CompletionHandler public class GFG { // Method 1 // Main driver method public static void main(String[] args) throws Exception { // Calling the writefile() method writeFile(); } // Method 2 // To write into a file private static void writeFile() throws IOException { // Custom string String input = "Content to be written to the file." ; System.out.println( "Input string: " + input); byte [] byteArray = input.getBytes(); ByteBuffer buffer = ByteBuffer.wrap(byteArray); // Specifying path of File Path path = Paths.get( "C:/users/Sir/Desktop/fileCopy.txt" ); AsynchronousFileChannel channel = AsynchronousFileChannel.open( path, StandardOpenOption .WRITE); // calling the API CompletionHandler handler = new CompletionHandler() { // Method 3 @Override public void completed(Object result, Object attachment) { System.out.println( attachment + " completed and " + result + " bytes are written." ); } // Method 4 @Override public void failed(Throwable exc, Object attachment) { System.out.println( attachment + " failed with exception:" ); exc.printStackTrace(); } }; channel.write(buffer, 0 , "Async Task" , handler); // Closing the channel object that we created earlier // using close() method channel.close(); printFileContents(path.toString()); } // Method 5 // To print the file contents private static void printFileContents(String path) throws IOException { FileReader fr = new FileReader(path); BufferedReader br = new BufferedReader(fr); String textRead = br.readLine(); System.out.println( "File contents: " ); // Till there is some content in file while (textRead != null ) { System.out.println( " " + textRead); textRead = br.readLine(); } // Closing the fr object fr.close(); // Closing the br object br.close(); } } |
Output: