- Java NIO 教程
- Java NIO - 首页
- Java NIO - 概述
- Java NIO - 环境设置
- Java NIO vs JAVA IO
- Java NIO - 通道
- Java NIO - 文件通道
- Java NIO - 数据报通道
- Java NIO - 套接字通道
- Java NIO - 服务器套接字通道
- Java NIO - 散射
- Java NIO - 收集
- Java NIO - 缓冲区
- Java NIO - 选择器
- Java NIO - 管道
- Java NIO - 路径
- Java NIO - 文件
- Java NIO - 异步文件通道
- Java NIO - 字符集
- Java NIO - 文件锁
- Java NIO 有用资源
- Java NIO - 快速指南
- Java NIO - 有用资源
- Java NIO - 讨论
Java NIO - 异步文件通道
众所周知,Java NIO 支持并发和多线程,允许我们同时处理不同的通道。因此,Java NIO 包中负责此功能的 API 是 AsynchronousFileChannel,它定义在 NIO 通道包下。因此,AsynchronousFileChannel 的限定名称为java.nio.channels.AsynchronousFileChannel。
AsynchronousFileChannel 与 NIO 的 FileChannel 类似,区别在于此通道允许异步执行文件操作,不像同步 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<Integer> 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 -
这种方法非常简单,因为它使用 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.