十七、Java NIO AsynchronousFileChannel
所有文章
https://www.cnblogs.com/lay2017/p/12901123.html
正文
在Java7的时候,加入了AsynchronousFileChannel,使得你可以进行异步地read或write操作。本文关于如何使用AsynchronousFileChannel。
创建一个AsynchronousFileChannel
Path path = Paths.get("data/test.xml");
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
读取数据
读取数据有两种方式
通过Future读取
通过read获取Future,read方法会立即返回
Future<Integer> operation = fileChannel.read(buffer, 0);
下面是一个完整示例
AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); ByteBuffer buffer = ByteBuffer.allocate(1024); long position = 0; Future<Integer> operation = fileChannel.read(buffer, position); while(!operation.isDone()); buffer.flip(); byte[] data = new byte[buffer.limit()]; buffer.get(data); System.out.println(new String(data)); buffer.clear();
示例中read直接返回了Future,通过Future不断轮询是否完成。完成以后,数据已经进入buffer。再从buffer读取数据并打印
通过CompletionHandler
除了通过Future主动轮询之外,还可以通过CompletionHandler接口的回调处理,示例代码如下
fileChannel.read(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void completed(Integer result, ByteBuffer attachment) { System.out.println("result = " + result); attachment.flip(); byte[] data = new byte[attachment.limit()]; attachment.get(data); System.out.println(new String(data)); attachment.clear(); } @Override public void failed(Throwable exc, ByteBuffer attachment) { } });
我们看到,completed在正常回调的时候触发。failed回调在失败的时候触发
写入数据
与读取数据类似,写入数据同样支持两种方式
通过Future写入
Path path = Paths.get("data/test-write.txt"); AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE); ByteBuffer buffer = ByteBuffer.allocate(1024); long position = 0; buffer.put("test data".getBytes()); buffer.flip(); Future<Integer> operation = fileChannel.write(buffer, position); buffer.clear(); while(!operation.isDone()); System.out.println("Write done");
写入数据要注意file必须存在,否则会抛出NoSuchFileException。你可以这样创建文件
if(!Files.exists(path)){ Files.createFile(path); }
通过CompletionHandler
Path path = Paths.get("data/test-write.txt"); if(!Files.exists(path)){ Files.createFile(path); } AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE); ByteBuffer buffer = ByteBuffer.allocate(1024); long position = 0; buffer.put("test data".getBytes()); buffer.flip(); fileChannel.write(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void completed(Integer result, ByteBuffer attachment) { System.out.println("bytes written: " + result); } @Override public void failed(Throwable exc, ByteBuffer attachment) { System.out.println("Write failed"); exc.printStackTrace(); } });
和read类似,write正常结束会回调completed,失败回调failed。