Java NIO AsynchronousFileChannel
In Java 7 the AsynchronousFileChannel was added to Java NIO. The AsynchronousFileChannel makes it possible to read data from, and write data to files asynchronously. This tutorial will explain how to use the AsynchronousFileChannel.
Creating an AsynchronousFileChannel
You create an AsynchronousFileChannel via its static method open(). Here is an example of creating an AsynchronousFileChannel:
Path path = Paths.get("data/test.xml");
AsynchronousFileChannel fileChannel =
AsynchronousFileChannel.open(path, StandardOpenOption.READ);
The first parameter to the open() method is a Path instance pointing to the file the AsynchronousFileChannel is to be associated with.
The second parameter is one or more open options which tell the AsynchronousFileChannel what operations is to be performed on the underlying file. In this example we used the StandardOpenOption.READ which means that the file will be opened for reading.
Reading Data
You can read data from an AsynchronousFileChannel in two ways. Each way to read data call one of the read() methods of the AsynchronousFileChannel. Both methods of reading data will be covered in the following sections.
Reading Data Via a Future
The first way to read data from an AsynchronousFileChannel is to call the read() method that returns a Future. Here is how calling that read() method looks:
Future<Integer> operation = fileChannel.read(buffer, 0);
This version of the read() method takes ByteBuffer as first parameter. The data read from the AsynchronousFileChannel is read into this ByteBuffer. The second parameter is the byte position in the file to start reading from.
The read() method return immediately, even if the read operation has not finished. You can check the when the read operation is finished by calling the isDone() method of the Future instance returned by the read() method.
Here is a longer example showing how to use this version of the read() method:
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();
This example creates an AsynchronousFileChannel and then creates a ByteBuffer which is passed to the read() method as parameter, along with a position of 0. After calling read() the example loops until the isDone() method of the returned Future returns true. Of course, this is not a very efficient use of the CPU - but somehow you need to wait until the read operation has completed.
Once the read operation has completed the data read into the ByteBuffer and then into a String and printed to System.out .
Reading Data Via a CompletionHandler
The second method of reading data from an AsynchronousFileChannel is to call the read() method version that takes a CompletionHandler as a parameter. Here is how you call this read() method:
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) {
}
});
Once the read operation finishes the CompletionHandler's completed() method will be called. As parameters to the completed() method are passed an Integer telling how many bytes were read, and the "attachment" which was passed to the read() method. The "attachment" is the third parameter to the read() method. In this case it was the ByteBuffer into which the data is also read. You can choose freely what object to attach.
If the read operation fails, the failed() method of the CompletionHandler will get called instead.
Writing Data
Just like with reading, you can write data to an AsynchronousFileChannel in two ways. Each way to write data call one of the write() methods of the AsynchronousFileChannel. Both methods of writing data will be covered in the following sections.
Writing Data Via a Future
The AsynchronousFileChannel also enables you to write data asynchronously. Here is a full Java AsynchronousFileChannel write example:
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");
First an AsynchronousFileChannel is opened in write mode. Then a ByteBuffer is created and some data written into it. Then the data in the ByteBuffer is written to the file. Finally the example checks the returned Future to see when the write operation has completed.
Note, that the file must already exist before this code will work. If the file does not exist the write() method will throw a java.nio.file.NoSuchFileException .
You can make sure that the file the Path points to exists with the following code:
if(!Files.exists(path)){
Files.createFile(path);
}
Writing Data Via a CompletionHandler
You can also write data to the AsynchronousFileChannel with a CompletionHandler to tell you when the write is complete instead of a Future. Here is an example of writing data to the AsynchronousFileChannel with a 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();
}
});
The CompletionHandler's completed() method will get called when the write operation completes. If the write fails for some reason, the failed() method will get called instead.
Notice how the ByteBuffer is used as attachment - the object which is passed on to the CompletionHandler's methods.
Ref:
http://tutorials.jenkov.com/java-nio/asynchronousfilechannel.html
Java NIO AsynchronousFileChannel的更多相关文章
- Java NIO学习系列七:Path、Files、AsynchronousFileChannel
相对于标准Java IO中通过File来指向文件和目录,Java NIO中提供了更丰富的类来支持对文件和目录的操作,不仅仅支持更多操作,还支持诸如异步读写等特性,本文我们就来学习一些Java NIO提 ...
- Java NIO 完全学习笔记(转)
本篇博客依照 Java NIO Tutorial翻译,算是学习 Java NIO 的一个读书笔记.建议大家可以去阅读原文,相信你肯定会受益良多. 1. Java NIO Tutorial Java N ...
- Java NIO 学习总结 学习手册
原文 并发编程网(翻译):http://ifeve.com/java-nio-all/ 源自 http://tutorials.jenkov.com/java-nio/index.html Java ...
- 海纳百川而来的一篇相当全面的Java NIO教程
目录 零.NIO包 一.Java NIO Channel通道 Channel的实现(Channel Implementations) Channel的基础示例(Basic Channel Exampl ...
- Java NIO文章列表(强烈推荐 转)
IO流学习总结 一 Java IO,硬骨头也能变软 二 java IO体系的学习总结 三 Java IO面试题 NIO与AIO学习总结 一 Java NIO 概览 二 Java NIO 之 Buffe ...
- Java NIO 学习笔记(六)----异步文件通道 AsynchronousFileChannel
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- Java NIO、NIO.2学习笔记
相关学习资料 http://www.molotang.com/articles/903.html http://www.ibm.com/developerworks/cn/education/java ...
- Java NIO 学习
Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(B ...
- Java NIO系列教程(八)JDK AIO编程
目录: Reactor(反应堆)和Proactor(前摄器) <I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor> <[转]第8章 前摄器(Proa ...
随机推荐
- 那些年我们踩过的坑之表单reset
开发者往往是在一个又一个的坑中成长起来的,自学的开发者尤其如此,刚刚填完一个坑,转身又掉进另一个坑.有些坑很容易就跳出来了,也有些坑能整了一天都没头绪,第二天早上一来发现后面就有一架通往坑外的梯子,坑 ...
- 使用ajax与jqplot的小体会
在使用ajax与jqplot时遇到了传值的问题!一开始都不知值是怎么传过去的,只找到了例子是以<div id="data">原始数据</div>这样子来接收 ...
- 【HDU 3590】 PP and QQ (博弈-Anti-SG游戏,SJ定理,树上删边游戏)
PP and QQ Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- 【学习笔记】python的代码块(吐槽)
曾经我以为python是像pascal那样begin开始end结束, 直到今天…… 我才知道python是用缩进作为代码段标识的…… >>> def test(n): ... if ...
- ELASTIC的备份与恢复
前言 elasticsearch官方并没有提供合适的备份工具,然而生产场景中备份却是的确需要的. 本文介绍了使用自己写的php脚本以及第三方工具来进行索引的备份,恢复以及删除等操作. 全量备份 ela ...
- POP3_收取QQ邮箱邮件的问题
今天纠结了一天的时间,使用pop3协议收取qq邮箱中邮件时,因为一个特别坑爹的问题重新写n次,最后发现是因为qq邮箱设置了独立邮箱密码,必须的用独立邮箱密码登陆才行,/(ㄒoㄒ)/~~!!!! 但今天 ...
- MySQL错误:TIMESTAMP with implicit DEFAULT value is deprecated
用于存放数据库的文件夹不为空,清空了再来一次!
- .net core中的高效动态内存管理方案
.net core在新增的System.Buffers中引入了一大堆高效内存管理的类,如span和memory.内存池.本文今天这里介绍一个高效动态内存访问方案. ReadOnlySequenceSe ...
- 【Go命令教程】7. go run
Go 源码文件包括:命令源码文件.库源码文件 和 测试源码文件.其中,命令源码文件 总应该属于 main 代码包,且在其中有无参数声明.无结果声明的 main 函数.单个命令源码文件可以被单独编译,也 ...
- WinForm基于插件开发实现多项配置存储
一.课程介绍和实例在线演示 明人不说暗话,跟着阿笨一起玩WinForm.本次分享课程属于<C#高级编程实战技能开发宝典课程系列>中的一部分,阿笨后续会计划将实际项目中的一些比较实用的关于C ...