📅  最后修改于: 2020-11-14 10:15:50             🧑  作者: Mango
我们知道Java NIO支持并发和多线程,这允许我们同时处理不同的通道,因此Java NIO包中负责此操作的API是AsynchronousFileChannel,它在NIO通道包下定义,因此限定名称对于AsynchronousFileChannel是java.nio.channels.AsynchronousFileChannel 。
AsynchronousFileChannel与NIO的FileChannel相似,不同之处在于此通道使文件操作能够异步执行,这与同步I / O操作不同,在同步I / O操作中,线程进入操作并等待请求完成。因此,异步通道是可以安全使用的通过多个并发线程。
在异步中,线程将请求传递给操作系统的内核以完成请求,而线程继续处理另一个作业。一旦内核的作业完成,它将向线程发出信号,然后线程确认信号并中断当前作业并处理I / O工作根据需要。
为了实现并发性,此通道提供了两种方法,其中一种方法是返回java.util.concurrent.Future对象,另一种方法是将类型为java.nio.channels.CompletionHandler的对象传递给操作。
我们将通过示例一一理解这两种方法。
Future对象-在这种情况下,从通道返回一个Future接口的实例。在Future接口中,有get()方法返回异步处理的操作状态,在此基础上可以确定其他任务的进一步执行。还可以通过调用isDone方法检查任务是否完成。
下面的示例演示如何使用Future对象以及如何异步执行任务。
package com.java.nio;
import java.io.BufferedReader;
import java.io.FileReader;
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 FutureObject {
public static void main(String[] args) throws Exception {
readFile();
}
private static void readFile() throws IOException, InterruptedException, ExecutionException {
String filePath = "D:fileCopy.txt";
printFileContents(filePath);
Path path = Paths.get(filePath);
AsynchronousFileChannel channel =AsynchronousFileChannel.open(path, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(400);
Future result = channel.read(buffer, 0); // position = 0
while (! result.isDone()) {
System.out.println("Task of reading file is in progress asynchronously.");
}
System.out.println("Reading done: " + result.isDone());
System.out.println("Bytes read from file: " + result.get());
buffer.flip();
System.out.print("Buffer contents: ");
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
System.out.println(" ");
buffer.clear();
channel.close();
}
private static void printFileContents(String path) throws IOException {
FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr);
String textRead = br.readLine();
System.out.println("File contents: ");
while (textRead != null) {
System.out.println(" " + textRead);
textRead = br.readLine();
}
fr.close();
br.close();
}
}
File contents:
To be or not to be?
Task of reading file is in progress asynchronously.
Task of reading file is in progress asynchronously.
Reading done: true
Bytes read from file: 19
Buffer contents: To be or not to be?
完成处理程序–
这种方法非常简单,因为在此方法中,我们使用CompletionHandler接口并覆盖其两个方法,一个是completed()方法,该方法在I / O操作成功完成时调用,另一个是failed()方法,如果I / O操作成功,则调用该方法在这种情况下,将创建一个处理程序以使用异步I / O操作的结果,因为一旦完成任务,则只有该处理程序具有已执行的功能。
以下示例显示了如何使用CompletionHandler异步执行任务。
package com.java.nio;
import java.io.BufferedReader;
import java.io.FileReader;
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 CompletionHandlerDemo {
public static void main (String [] args) throws Exception {
writeFile();
}
private static void writeFile() throws IOException {
String input = "Content to be written to the file.";
System.out.println("Input string: " + input);
byte [] byteArray = input.getBytes();
ByteBuffer buffer = ByteBuffer.wrap(byteArray);
Path path = Paths.get("D:fileCopy.txt");
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
CompletionHandler handler = new CompletionHandler() {
@Override
public void completed(Object result, Object attachment) {
System.out.println(attachment + " completed and " + result + " bytes are written.");
}
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println(attachment + " failed with exception:");
exc.printStackTrace();
}
};
channel.write(buffer, 0, "Async Task", handler);
channel.close();
printFileContents(path.toString());
}
private static void printFileContents(String path) throws IOException {
FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr);
String textRead = br.readLine();
System.out.println("File contents: ");
while (textRead != null) {
System.out.println(" " + textRead);
textRead = br.readLine();
}
fr.close();
br.close();
}
}
Input string: Content to be written to the file.
Async Task completed and 34 bytes are written.
File contents:
Content to be written to the file.