March 17, 2022

Read File Asynchronously in Java

This post shows how to read file in Java asynchronously using the java.nio.channels.AsynchronousFileChannel class. Using AsynchronousFileChannel you can create an asynchronous file channel for reading, writing, and manipulating a file.

To see how to write a file asynchronously in Java, check this post- Write a File Asynchronously in Java

Reading file using AsynchronousFileChannel

For reading a file there are two read methods-

  1. One of the read() method returns a Future instance representing the result of an asynchronous computation.
  2. In another read() method CompletionHandler instance is passed as an argument which consumes the result of an asynchronous I/O operation.

1. Java program to read file asynchronously

First let’s see a program which uses the read method that returns Future instance.

Future<Integer> read(ByteBuffer bufffer, long position)- Reads a sequence of bytes from this channel into the given buffer, starting at the given file position.

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.Future;

public class AsyncRead {
  public static void main(String[] args) {
    Path path = Paths.get("F:\\knpcode\\links.txt");
    // Create buffer into which data is read
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    // Create channel
    try(AsynchronousFileChannel asyncChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ)){
      Future<Integer> result = asyncChannel.read(buffer, 0);
      // Immediately returns here
      while(!result.isDone()) {
        System.out.println("Waiting for the asynchronous file read operation ..... ");
        System.out.println("Do some other processing");
      }
      // Reset current position to 0 and limit 
      // as current buffer position 
      buffer.flip();
      String data = new String(buffer.array()).trim();
      System.out.println(data);
      buffer.clear();            
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }        
  }
}

2. Read file asynchronously using CompletionHandler

There is another read method in AsynchronousFileChannel class for reading asynchronously which takes CompletionHandler as an argument.

read(ByteBuffer dst, long position, A attachment, CompletionHandler<Integer,? super A> handler)- Reads a sequence of bytes from this channel into the given buffer, starting at the given file position.

java.nio.channels.CompletionHandler interface has two callback methods-

  1. completed- This method is invoked when the I/O operation completes successfully.
  2. failed- This method is invoked if the I/O operations fails.
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;

public class AsyncRead {
  public static void main(String[] args) {
    Path path = Paths.get("F:\\knpcode\\links.txt");
    // Create buffer into which data is read (capacity in bytes)
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    // Create channel
    try(AsynchronousFileChannel asyncChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ)){
      asyncChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
        @Override
        public void completed(Integer result, ByteBuffer attachment) {
          System.out.println("Number of bytes read- " + result);
          attachment.flip();
          String data = new String(attachment.array()).trim();
          System.out.println(data);
          attachment.clear();
        }

        @Override
        public void failed(Throwable exc, ByteBuffer attachment) {
          System.out.println("Read operation failed- " + exc.getMessage());
          
        }			
      });
      System.out.println("Waiting for the asynchronous file read operation");
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }		
  }
}

Once the I/O operation finishes, completed() method is called. First argument of the completed() method is of type Integer specifying the number of bytes read. Type of the second argument “attachment” corresponds to the type of the third argument to the read() method, ByteBuffer in this case. Attachment specifies the buffer containing the content.

That's all for the topic Read File Asynchronously in Java . If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment