Java I/O发展

Java I/O的发展阶段可以分为三个阶段:

  • JDK 1.4 之前的 同步阻塞模式 BIO
  • JDK 1.4 推出 Java NIO,提供了异步非阻塞 I/O;
  • JDK 1.7 推出 Java NIO 2.0,将原来的NIO类库进行了升级。

BIO

从 JDK 1.1 到 JDK 1.3 Java I/O类库都非常原始,很多 UNIX 网络编程中的概念或者接口在I/O类库中都没有体现,例如:Pipe、Channel、Buffer和Selector等。

NIO

2002年发布 JDK 1.4,提供了非阻塞开发的类库和API,主要的类和接口有:

  • 进行 I/O 操作的缓冲区 ByteBuffer 等。
  • 进行 I/O 操作的管道 Pipe 等。
  • 进行各种 I/O 操作(阻塞或非阻塞)的 Channel,包括 ServerSocketChannel 和 SocketChannel。
  • 多种字符集的编码和解码能力。
  • 实现非阻塞 I/O 的多路复用器 Selector。
  • 基于流行的 Perl 实现的正则表达式类库。
  • 文件通道 FileChannel(不支持非阻塞模式),但是有内存映射(Memory Mapping)的特性。

NIO和传统的IO有相同的目的,都是用于进行输入/输出,但 NIO 采用内存映射文件的方式来处理输入/输出,NIO 将文件或文件的一段区域映射到内存中,这样就可以像访问内存一样来访问文件了。

NIO仍有不足,特别是对文件系统的处理能力:

  • 没有统一的文件属性(例如 读写权限)。
  • API 能力较弱,例如 目录的级联创建和递归遍历需要自己实现。
  • 底层存储系统的一些高级 API 无法使用。
  • 所有的文件操作都是同步阻塞调用,不支持异步文件读写操作。

NIO 2.0

2011年发布 JDK 1.7,对原来的 NIO 类库进行了升级,被称为 NIO 2.0。

主要有以下改进:

  • 提供能够批量获取文件属性的 API,这些 API 具有平台无关性。另外还提供了标准文件系统的 SPI,供各个服务提供商扩展实现。
  • 提供 AIO 功能,支持基于文件的异步 I/O 操作和针对网络套接字的异步操作。
  • 完成了通道功能,包括对配置和多播数据报的支持等。

凡是需要由应用程序将数据读写到应用程序内存中的 I/O,都是同步I/O;比如上面的 BIO 与 NIO。相对的,凡是由操作系统来完成读写的,就是异步I/O。

举例而言,在 NIO 中,当应用程序检测到某个Channel有可读数据时,必须显示发起一个read请求。而在异步I/O中,应用程序仅仅需要告诉操作系统,我需要什么数据,并提供给OS一个Buffer和一个回调。OS会自己检测Channel的可读性,但其发起其可读,会自动将数据复制到Buffer中,并通知应用程序任务完成。