java8 AIO AsynchronousFileChannel例

本文介绍了一个使用Java NIO的AsynchronousFileChannel进行文件异步读写的示例。通过两个不同的方法演示了如何利用Future和CompletionHandler来处理读取操作,并展示了如何将读取的数据写回到另一个文件中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.kd.nio;

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;
import java.util.concurrent.Future;


public class AsynchronousFileChannelTest {
	public static ByteBuffer read()throws Exception{
		Path path = Paths.get("f:","test1.txt");
  		AsynchronousFileChannel afc = AsynchronousFileChannel.open(path , StandardOpenOption.READ) ;
  		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
  		
  		
  		Future<Integer> read = afc.read(byteBuffer, 0);
  		
  		while(!read.isDone()){
  			System.out.println("reading");
  		}
  		System.out.println(read.isDone());
  		
  		System.out.println(byteBuffer);
  		afc.close();
  		return byteBuffer;
	}
	
	public static void read2()throws Exception{
		Path path = Paths.get("f:","test1.txt");
  		AsynchronousFileChannel afc = AsynchronousFileChannel.open(path , StandardOpenOption.READ) ;
  		ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
  		
  		
  		 afc.read(byteBuffer, 0, "at", new CompletionHandler<Integer,Object>(){

			@Override
			public void completed(Integer result, Object attachment) {
				System.out.println(attachment+"/"+result);
				System.out.println(byteBuffer);
				try {
					write2(byteBuffer);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			@Override
			public void failed(Throwable exc, Object attachment) {
				
			}
  			 
  		 });
  		
  		Thread.sleep(5000);
  		System.out.println("close");
  		afc.close();
	}
	
	public static void write(ByteBuffer byteBuffer)throws Exception{
		Path path = Paths.get("f:","test.txt");
  		AsynchronousFileChannel afc = AsynchronousFileChannel.open(path , StandardOpenOption.CREATE,StandardOpenOption.WRITE) ;
  		byteBuffer.flip();
  		Future<Integer> write = afc.write(byteBuffer, 0);
  		while(!write.isDone()){
  			System.out.println("writing");
  		}
  		System.out.println(write.isDone());
  		System.out.println(byteBuffer);
  		afc.close();
	}
	
	public static void write2(ByteBuffer byteBuffer)throws Exception{
		Path path = Paths.get("f:","test.txt");
  		AsynchronousFileChannel afc = AsynchronousFileChannel.open(path , StandardOpenOption.CREATE,StandardOpenOption.WRITE) ;
  		byteBuffer.flip();
  		afc.write(byteBuffer, 0, "attachment",  new CompletionHandler<Integer,Object>(){

			@Override
			public void completed(Integer result, Object attachment) {
				System.out.println(result+"/"+attachment);
				System.out.println(byteBuffer);
			}

			@Override
			public void failed(Throwable exc, Object attachment) {
				System.out.println(byteBuffer);
			}
  			
  		});
  		
  		Thread.sleep(5000);
  		System.out.println("close");
  		afc.close();
  	
  		
	}
     
      public static void main(String[] args) throws Exception{
    	
    	 read2();
  		
	}
	

}

<think>嗯,用户这次聚焦在Java AIO的具体实现类上,看来是之前讨论BIO/NIO/AIO对比后的技术深挖。用户引用的资料[2][3][4]特别强调了AIO在JDK7+的实现细节,尤其是Linux和Windows系统的差异,这个点需要重点展开。 用户可能正在准备面试,或者开发需要AIO的实际项目。从ta特意追问“具体实现类”来看,ta需要的是可直接编码的API参考,而不仅是理论概念。之前回答里提到过AsynchronousServerSocketChannel,但显然ta需要更完整的类清单。 引用[3]和[4]提供了关键线索:JDK的AIO实现实际是NIO.2包,在Windows用IOCP而在Linux用自建线程池模拟。这个底层差异会影响API设计,但用户暂时只需要接口层面的类,所以先列出核心类再说注意事项比较合理。 四个核心类必须覆盖: 1. AsynchronousServerSocketChannel - 对应BIO的ServerSocket 2. AsynchronousSocketChannel - 最常用的客户端通道 3. AsynchronousFileChannel - 用户引用[5]的聊天室案用了这个 4. CompletionHandler - 回调机制的核心,用户引用[2]强调过“异步能力” 特别要注意AsynchronousChannelGroup这个线程池控制器,用户引用[3]提到JDK在Linux的线程池方案,这个类就是入口。示代码选用户引用[5]的聊天室片段最贴切,但需要简化到只展示API调用关系。 最后补充系统差异时,用“开发者注意”的委婉说法比直接说“Linux有缺陷”更专业。延伸问题设计成阶梯状:从编码(实现类用法)到原理(线程模型)再到实战(Netty整合),这样用户后续追问也有脉络可循。</think>在 Java 中,AIO(Asynchronous I/O)的实现类主要位于 `java.nio.channels` 包中,是 **NIO.2** 的核心组成部分(JDK 7+ 支持)。以下是关键实现类及其作用: --- ### **核心实现类** #### 1. **`AsynchronousServerSocketChannel`** - **作用**:异步 TCP 服务端通道,监听客户端连接请求。 - **关键方法**: ```java void accept(A attachment, CompletionHandler<AsynchronousSocketChannel,? super A> handler) ``` - **示**: ```java AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open(); server.bind(new InetSocketAddress(8080)); server.accept(null, new CompletionHandler<>() { @Override public void completed(AsynchronousSocketChannel client, Object attachment) { // 新连接建立后的回调逻辑 } @Override public void failed(Throwable exc, Object attachment) { // 处理异常 } }); ``` **适用场景**:异步 TCP 服务器(如聊天室服务端)[^5]。 --- #### 2. **`AsynchronousSocketChannel`** - **作用**:异步 TCP 客户端通道,处理读写操作。 - **关键方法**: ```java Future<Integer> read(ByteBuffer dst) // 异步读(Future 方式) <A> void read(ByteBuffer dst, A attachment, CompletionHandler<Integer,? super A> handler) // 回调方式 Future<Integer> write(ByteBuffer src) // 异步写(Future 方式) <A> void write(ByteBuffer src, A attachment, CompletionHandler<Integer,? super A> handler) // 回调方式 ``` - **示**(客户端发送消息): ```java AsynchronousSocketChannel client = AsynchronousSocketChannel.open(); client.connect(new InitSocketAddress("localhost", 8080)).get(); ByteBuffer buffer = ByteBuffer.wrap("Hello".getBytes()); client.write(buffer, null, new CompletionHandler<>() { @Override public void completed(Integer bytesWritten, Object attachment) { // 数据发送成功 } @Override public void failed(Throwable exc, Object attachment) { // 处理异常 } }); ``` **适用场景**:异步客户端通信(如聊天室客户端)[^5]。 --- #### 3. **`AsynchronousFileChannel`** - **作用**:异步文件 I/O 通道,支持非阻塞文件读写。 - **关键方法**: ```java Future<Integer> read(ByteBuffer dst, long position) Future<Integer> write(ByteBuffer src, long position) ``` - **示**(异步读取文件): ```java Path path = Paths.get("data.txt"); AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); ByteBuffer buffer = ByteBuffer.allocate(1024); fileChannel.read(buffer, 0, buffer, new CompletionHandler<>() { @Override public void completed(Integer bytesRead, ByteBuffer attachment) { // 文件读取完成 } @Override public void failed(Throwable exc, ByteBuffer attachment) { // 处理异常 } }); ``` **适用场景**:大文件异步读写(如日志处理)[^2][^4]。 --- #### 4. **`CompletionHandler<V, A>` 接口** - **作用**:定义异步操作完成后的回调逻辑。 - **核心方法**: ```java void completed(V result, A attachment); // 操作成功时调用 void failed(Throwable exc, A attachment); // 操作失败时调用 ``` - **说明**:所有异步操作均通过此接口处理结果,是 AIO 事件驱动的核心[^2][^4]。 --- #### 5. **`AsynchronousChannelGroup`** - **作用**:管理异步通道的线程池资源。 - **创建方式**: ```java // 使用固定线程池 AsynchronousChannelGroup group = AsynchronousChannelGroup.withFixedThreadPool(10, Executors.defaultThreadFactory()); AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open(group); ``` - **意义**:优化线程资源分配,避免频繁创建/销毁线程[^3]。 --- ### **底层实现差异** - **Windows 系统**: 直接使用操作系统的 **IOCP(I/O Completion Ports)** 实现高性能异步 I/O[^3]。 - **Linux 系统**: JDK 未直接使用 Linux 原生 AIO(因限制多、性能一般),而是通过**自建线程池模拟异步行为**(本质仍是 NIO 多路复用 + 线程池)[^1][^3]。 --- ### **总结:AIO 核心类关系** ```mermaid graph TD A[AsynchronousChannel] --> B[AsynchronousServerSocketChannel] A --> C[AsynchronousSocketChannel] A --> D[AsynchronousFileChannel] E[CompletionHandler] -->|回调机制| B E -->|回调机制| C E -->|回调机制| D F[AsynchronousChannelGroup] -->|管理线程资源| B F -->|管理线程资源| C F -->|管理线程资源| D ``` > **开发者注意**:Linux 下 AIO 性能可能不及预期,高并发场景推荐使用 Netty(基于 NIO 优化)[^3][^4]。 --- ### 相关问题延伸 1. **`AsynchronousSocketChannel` 如何实现超时控制?** 2. **Linux 下 JDK 的 AIO 线程池模型是怎样的?** 3. **为什么 Netty 未使用 AIO 作为底层?** 4. **AIO 的 `CompletionHandler` 是否线程安全?** 5. **如何用 AIO 实现异步文件复制?** 需要具体代码示或场景解析可进一步说明!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值