用Java异步读取文件

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

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

要查看如何用Java异步编写文件,请查看此文章用Java异步编写文件

使用AsynchronousFileChannel读取文件

为了读取文件,有两种读取方法:

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

1. Java程序异步读取文件

首先,让我们看一个使用read方法返回Future实例的程序。

Future <Integer> read(ByteBuffer bufffer,long 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:\theitroad\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.使用CompletionHandler异步读取文件

AsynchronousFileChannel类中还有另一个用于异步读取的读取方法,该方法以CompletionHandler作为参数。

read(ByteBuffer dst,long position,一个附件,CompletionHandler <Integer ,? super A>处理程序)从该通道从给定文件位置开始将字节序列读入给定缓冲区。

java.nio.channels.CompletionHandler接口具有两个回调方法

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 AsyncRead {
  public static void main(String[] args) {
    Path path = Paths.get("F:\theitroad\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();
    }		
  }
}

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