Saturday, April 20, 2024

Writing a File Asynchronously Java Program

In this post we’ll see how to write a file asynchronously in Java using java.nio.channels.AsynchronousFileChannel class added in Java 7. Using AsynchronousFileChannel class you can create an asynchronous channel for reading, writing, and manipulating a file.

To see how to read a file asynchronously in Java, refer this post- Read File Asynchronously Java Program

Opening an Asynchronous channel

Whether you are reading or writing a file asynchronously first thing you need to do is to create an asynchronous channel. For that you need to use static open() method of the AsynchronousFileChannel class which opens or creates a file for reading or writing, returning an asynchronous file channel to access the file.

Following code snippet shows how you can create an asynchronous file channel for writing to a file.

Path path = Paths.get("F:\\netjs\\WriteFile.txt");
AsynchronousFileChannel asyncFileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE)

Writing file asynchronously using AsynchronousFileChannel class

For writing a file asynchronously there are two versions of write() method in the AsynchronousFileChannel class.

  1. write() method that writes the passed buffer to the file and returns a Future representing the result of the write operation.
  2. write() method where you pass CompletionHandler instance as an argument.

We’ll see examples of of both of these ways to write a file asynchronously to have a better idea.

Writing to a file asynchronously in Java

1. In the first Java program we’ll use the write method that returns a Future.

Future<Integer> write(ByteBuffer src, long position)- This method writes a sequence of bytes to this channel from the passed 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.ExecutionException;
import java.util.concurrent.Future;

public class AsyncFileWrite {
  public static void main(String[] args) {
    Path path = Paths.get("F:\\netjs\\test.txt");
    // increase the buffer size if required
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    // Write Data to buffer
    buffer.put("This will be written to a file.".getBytes());
    buffer.flip();
    try(AsynchronousFileChannel asyncChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE)){
      // Write to async channel from buffer
      // starting from position 0
      Future<Integer> future =  asyncChannel.write(buffer, 0);
      while(!future.isDone()) {
        System.out.println("Waiting for async write operation... ");
        // You can do other processing
      }            
      buffer.clear();            
      System.out.println("Total bytes written- " + future.get());
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } 
  }
}

2. In this Java program for writing file asynchronously we’ll use the write() method where CompletionHandler instance is passed as an argument.

CompletionHandler interface defines two callback methods which you need to implement.

  • completed(V result, A attachment)- Invoked when an operation has completed.
  • failed(Throwable exc, A attachment)- Invoked when an operation fails.
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.nio.channels.CompletionHandler;

public class AsyncFileWrite {
  public static void main(String[] args) throws IOException {
    Path path = Paths.get("F:\\netjs\\test.txt");
    if(!Files.exists(path)){
      Files.createFile(path);
    }
    // increase the buffer size if required
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    // Write Data to buffer
    buffer.put("This will be written to a file.".getBytes());
    buffer.flip();
    try(AsynchronousFileChannel asyncChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE)){
      // Write to channel from buffer, start from position 0
      asyncChannel.write(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
        @Override
        public void completed(Integer result, ByteBuffer attachment) {
          System.out.println("Total bytes written- " + result);
        }

        @Override
        public void failed(Throwable ex, ByteBuffer attachment) {
          System.out.println("Write operation failed- " + ex.getMessage());                    
        }
      });            
    }
  }
}

That's all for this topic Writing a File Asynchronously Java Program. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. Write to a File in Java
  2. How to Append to a File in Java
  3. How to Write Excel File in Java Using Apache POI
  4. Creating Temporary File in Java
  5. Reading File in Java Using BufferedReader

You may also like-

  1. How to Create Password Protected Zip File in Java
  2. Creating PDF in Java Using Apache PDFBox
  3. Arrange Non-Negative Integers to Form Largest Number - Java Program
  4. Invoking Getters And Setters Using Reflection in Java
  5. HashMap in Java With Examples
  6. Interface in Java
  7. Passing Arguments to getBean() Method in Spring
  8. YARN in Hadoop