目录:

Java NIO 学习笔记(一)----概述,Channel/Buffer

Java NIO 学习笔记(二)----聚集和分散,通道到通道

Java NIO 学习笔记(三)----Selector

Java NIO 学习笔记(四)----文件通道和网络通道

Java NIO 学习笔记(五)----路径、文件和管道 Path/Files/Pipe

Java NIO 学习笔记(六)----异步文件通道 AsynchronousFileChannel

Java NIO 学习笔记(七)----NIO/IO 的对比和总结

AsynchronousFileChannel 异步文件通道

在 Java 7 中,AsynchronousFileChannel 已添加到 Java NIO 中,它可以异步读取数据并将数据写入文件。先说明,异步和阻塞/非阻塞没有关系,下面简单介绍一下相关概念:

  1. 阻塞是线程的一个状态,线程发起任务请求然后一直等,直到到任务完成再把结果返回,如果任务未完成当前线程会被挂起。
  2. 非阻塞是发起任务请求之后先马上返回去做别的事,然后再时不时主动查看任务请求是否被完成。(轮询)
  3. 同步是同时只能有一个线程处理某个对象或者操作,例如一个线程占用了一个对象,其他线程如果要访问此对象,则需要等之前得线程操作完成返回,相关概念有同步方法、同步代码块、对象锁。
  4. 异步是如果完成任务时,遇到一个耗时操作(或者对象已经被别的线程占用了),不等待而是去做其他事情,也不主动查看是否完成,而是等耗时操作完成,发通知再叫线程回来处理结果,常见的例子就是 Ajax ,相关概念有回调函数等。

一般异步都是和非阻塞组合使用的。

创建 AsynchronousFileChannel

通过其静态方法 open() 创建 AsynchronousFileChannel ,下面是一个示例:

Path path = Paths.get("D:\\test\\input.txt");

AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);

// 作为对比,普通的 FileChannel 是这样打开的:
RandomAccessFile aFile = new RandomAccessFile("D:\\test\\input.txt", "rw");
FileChannel inChannel = aFile.getChannel();

open() 方法的第一个参数是指向 AsynchronousFileChannel 要关联的文件的 Path 实例。第二个参数是可选的,可以是一个或多个打开选项,这些选项告诉 AsynchronousFileChannel 在底层文件上执行什么操作。在这个例子中,我们使用了 StandardOpenOption.READ,这意味着该文件将被打开以供阅读。

读取数据

可以通过两种方式从 AsynchronousFileChannel 读取数据,都是调用 read() 方法之一完成的。

Future<Integer> read(ByteBuffer dst, long position);

<A> void read(ByteBuffer dst,
long position,
A attachment,
CompletionHandler<Integer,? super A> handler);

通过 Future 读取数据

Future 是 Java 多线程方面的内容,后面我会再继续学习多线程的知识,这里先稍微了解,带过。

首先这个 Futrue 类有什么用?我们知道多线程编程的时候,一般使用 Runable ,重写 run() 方法,然后调用线程对象的 start() 方法,重点就在 run() 方法的返回值是 void ,那如果我们需要线程执行完成后返回结果怎么办,Future 就可以解决这个问题。

从 AsynchronousFileChannel 读取数据的第一种方法是调用 read() 方法,该方法返回 Future :

Future<Integer> operation = fileChannel.read(buffer, 0);

此版本的 read() 方法将 ByteBuffer 作为第一个参数。 从 AsynchronousFileChannel 读取的数据被读入此 ByteBuffer ,第二个参数指定文件中要开始读取的字节位置。

即使读取操作尚未完成,read() 方法也会立即返回,可以通过调用 read() 方法返回的 Future 实例的 isDone() 方法来检查读取操作何时完成。这是一个示例:

Path path = Paths.get("D:\\test\\input.txt");
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;
Future<Integer> operation = channel.read(buffer, position); while (!operation.isDone()) ; buffer.flip();
System.out.println(new String(buffer.array()));

此示例创建一个 AsynchronousFileChannel ,然后创建一个 ByteBuffer ,它作为参数传递给 read() 方法,并且位置为 0 ,在调用 read() 之后,循环调用 Future 的 isDone() 方法直到返回 true。 当然,这不是一个非常有效的 CPU 使用,但是这里需要等待读取操作完成。读取操作完成后,将数据读入 ByteBuffer 并输出。

通过 CompletionHandler 读取数据

从 AsynchronousFileChannel 读取数据的第二种方法是调用以 CompletionHandler 作为参数的 read() 方法版本,其第二个参数 position 可指定从什么位置开始读取。 以下是调用此 read() 方法的示例:

Path path = Paths.get("D:\\test\\input.txt");
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path); ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
System.out.println("result: " + result);
attachment.flip();
System.out.println(new String(attachment.array()));
attachment.clear();
} @Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println("failed");
}
});

一旦读取操作完成,将调用 CompletionHandler 的 completed() 方法,completed() 方法的第一个参数是 Integer 类型,表示读取了多少字节,attachment 对应 read() 方法的第三个参数。 在这个例子中也是 ByteBuffer,数据也被读入其中。 可以自由选择要附加的对象。如果读取操作失败,则将调用 CompletionHandler 的 failed() 方法。

写入数据

和读取数据类似,也可以通过 AsynchronousFileChannel 对象的 2 种方法写入数据:

Future<Integer> write(ByteBuffer src, long position);

<A> void write(ByteBuffer src,
long position,
A attachment,
CompletionHandler<Integer,? super A> handler);

具体的操作请参考读取数据,这里不展开了。

Java NIO 学习笔记(六)----异步文件通道 AsynchronousFileChannel的更多相关文章

  1. Java NIO学习笔记五 FileChannel(文件通道)

    Java NIO FileChannel Java NIO FileChannel是连接文件的通道.使用FileChannel,您可以从文件中读取数据和将数据写入文件.Java NIO FileCha ...

  2. Java NIO学习笔记六 SocketChannel 和 ServerSocketChannel

    Java NIO SocketChannel Java NIO SocketChannel是连接到TCP网络socket(套接字)的通道.Java NIO相当于Java Networking的sock ...

  3. Java NIO 学习笔记(四)----文件通道和网络通道

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  4. Java NIO 学习笔记(五)----路径、文件和管道 Path/Files/Pipe

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  5. Java NIO 学习笔记(二)----聚集和分散,通道到通道

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  6. Java IO学习笔记六:NIO到多路复用

    作者:Grey 原文地址:Java IO学习笔记六:NIO到多路复用 虽然NIO性能上比BIO要好,参考:Java IO学习笔记五:BIO到NIO 但是NIO也有问题,NIO服务端的示例代码中往往会包 ...

  7. Java NIO 学习笔记(七)----NIO/IO 的对比和总结

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  8. Java NIO 学习笔记(三)----Selector

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  9. Java NIO 学习笔记(一)----概述,Channel/Buffer

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

随机推荐

  1. FastDFS安装、配置、部署(三)-Storage配置具体解释

    1.基本配置 # is this config file disabled # false for enabled # true for disabled disabled=false # the n ...

  2. silverlight,WPF动画终极攻略之会飞的小鸟篇(Blend 4开发)

    原文:silverlight,WPF动画终极攻略之会飞的小鸟篇(Blend 4开发) 本教程基本涵盖了WPF和silverlight中的各种动画.先上张效果图. 声明下,这个做的不是让大家照搬的,只是 ...

  3. ASP.NET Core MVC 设计模式 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core MVC 设计模式 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core MVC 设计模式 上一章节中,我们提到 ASP.NET Co ...

  4. WPF旋转的界面实现

    原文:WPF旋转的界面实现 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/article/details/1821534 ...

  5. 经典数字图像处理(matlab 实现)

    Ivan Selesnick(Software) Sparsity / Total variation / Denoising Software - Michael Elad's Personal P ...

  6. 一个JSP结果页面tomcat内存溢出

    如今,试验组的同事寻找新能源我看到一个奇怪的现象.一个tomcat应用,内只有一个简单的jsp页面,和这个jsp无论是什么页java代码(我想用这个jsp在她的网页测试server一对tomcat的最 ...

  7. Nginx之Eclipse开发环境配置

    C开发的IDE很多,为什么使用Eclipse?原因: 1. 历史原因:使用eclipse时间长,比较熟悉. 2. 功能原因:使用eclipse查看源码,可以在各个函数与头文件间直接跳转.这是所谓号称& ...

  8. WPF中Style文件的引用——使用xaml代码或者C#代码动态加载

    原文:WPF中Style文件的引用--使用xaml代码或者C#代码动态加载 WPF中控件拥有很多依赖属性(Dependency Property),我们可以通过编写自定义Style文件来控制控件的外观 ...

  9. 芯片超Intel,盈利比肩Apple,三星成科技界"全民公敌"

    原标题:芯片超英特尔,盈利比肩苹果:三星现在是科技界“全民公敌”了   当人们津津乐道于三星的手机业务或者是电视业务时,它已静悄悄的拿下了芯片行业的第一,并且凭借着在芯片上的巨大获利让它的老对手们眼红 ...

  10. 2018-4-25 1.如何在GitHub上新建一个新的项目并下载该项目及如何提交新的文件