用Java异步编写文件

时间:2020-01-09 10:35:38  来源:igfitidea点击:

这篇文章展示了如何使用java.nio.channels.AsynchronousFileChannel类在Java中异步编写文件。使用AsynchronousFileChannel,我们可以创建一个异步文件通道来读取,写入和操作文件。

使用AsynchronousFileChannel写入文件

就像异步读取文件一样,对于异步写入,也有两种写入方法:

  1. write()方法之一返回一个Future实例,该实例表示异步计算的结果。
    2.在另一个write()方法中,CompletionHandler实例作为参数传递,该参数消耗异步I / O操作的结果。

1. Java程序异步写入文件

首先,我们将使用write方法返回Future实例。

Future <Integer> write(ByteBuffer src,long position)–从给定文件位置开始,从给定缓冲区(由src表示)向此通道写入字节序列。该方法返回一个Future,表示写操作的未决结果。 Future的get方法返回写入的字节数。

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 AsyncWrite {
  public static void main(String[] args) {
    // Path to the file for write operation
    Path path = Paths.get("F:\theitroad\Write.txt");
    // Create buffer acting as data source
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    // Data that has to be written
    buffer.put("This is test data".getBytes());
    // Reset current position to 0 and limit 
    // as current buffer position 
    buffer.flip();
    try(AsynchronousFileChannel asyncChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE)){
      // Write from buffer, start from position 0
      Future<Integer> future =  asyncChannel.write(buffer, 0);
      while(!future.isDone()) {
        System.out.println("Waiting for the asynchronous file write operation ..... ");
        System.out.println("Do some other processing");
      }   
      buffer.clear();
      
      System.out.println("Write operation done, bytes written- " + future.get());
    } catch (IOException | InterruptedException | ExecutionException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

2.使用CompletionHandler异步写入文件

在这个用于异步写入文件的Java程序中,我们将使用另一个以CompletionHandler作为参数的写入方法。

公共摘要<A> void write(字节缓冲区src,长位置,附件,CompletionHandler <Integer ,? super A>处理程序)–从给定的文件位置开始,从给定的缓冲区向此通道写入字节序列。

java.nio.channels.CompletionHandler接口具有两个使用此write方法时需要实现的回调方法。

  1. Completed –当I / O操作成功完成时,将调用此方法。
  2. failed –如果I / O操作失败,则调用此方法。
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 AsyncWrite {
  public static void main(String[] args) {
    // Path to the file for write operation
    Path path = Paths.get("F:\theitroad\Write.txt");
    // Create buffer acting as data source
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    // Data that has to be written
    buffer.put("This is test data".getBytes());
    // Reset current position to 0 and limit 
    // as current buffer position 
    buffer.flip();
    try(AsynchronousFileChannel asyncChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE)){
      // Write 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("Write operation done, bytes written- " + result);
          attachment.clear();
        }

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

I / O操作完成后,将调用completed()方法。 completed()方法的第一个参数的类型为Integer,指定写入的字节数。第二个参数" attachment"的类型对应于write()方法的第三个参数的类型,在这种情况下为ByteBuffer。附件指定包含内容的缓冲区。