Java - Use CompletionHandler to handle the results of an asynchronous read from a file.

Introduction

The program reads and prints the contents a text file in the default directory.

To read the contents of a different file, change the path of the file in the main() method.

Demo

import static java.nio.file.StandardOpenOption.READ;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;

class Attachment {
  public Path path;
  public ByteBuffer buffer;
  public AsynchronousFileChannel asyncChannel;
}

// An inner class to handle completion of the asynchronous read operation
class ReadHandler implements CompletionHandler<Integer, Attachment> {
  @Override/* ww  w .  j a  v  a  2s .c  o m*/
  public void completed(Integer result, Attachment attach) {
    System.out.format("%s bytes read from %s%n", result, attach.path);

    System.out.format("Read data is:%n");

    byte[] byteData = attach.buffer.array();
    Charset cs = Charset.forName("UTF-8");
    String data = new String(byteData, cs);
    System.out.println(data);

    try {
      // Close the channel
      attach.asyncChannel.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  @Override
  public void failed(Throwable e, Attachment attach) {
    System.out.format("Read operation on %s file failed."
        + "The error is: %s%n", attach.path, e.getMessage());

    try {
      // Close the channel
      attach.asyncChannel.close();
    } catch (IOException e1) {
      e1.printStackTrace();
    }
  }
}

public class Main {

  public static void main(String[] args) {
    Path path = Paths.get("data.txt");
    try {
      // Get an async channel
      AsynchronousFileChannel afc = AsynchronousFileChannel.open(path, READ);

      // Get a completion handler
      ReadHandler handler = new ReadHandler();
      // Get the data size in bytes to read
      int fileSize = (int) afc.size();
      ByteBuffer dataBuffer = ByteBuffer.allocate(fileSize);

      // Prepare the attachment
      Attachment attach = new Attachment();
      attach.asyncChannel = afc;
      attach.buffer = dataBuffer;
      attach.path = path;

      // Perform the asynchronous read operation
      afc.read(dataBuffer, 0, attach, handler);

      try {
        // Let the thread sleep for five seconds,
        // to allow the asynchronous read to complete
        System.out.println("Sleeping for 5 seconds...");
        Thread.sleep(5000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }

      System.out.println("Done...");
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

Result

Related Topic