Java NIO 介绍
- NIO API 是对 1.3 版 I/O 特性的补充而非取代
- 新的 I/O 特性主要包含在 java.nio 软件包及其子包中,并被命 名为 New I/O(NIO)
- 主要用来提升 Java 应 用程序的 I/O 效率
Java NIO 的背景
Java 的劣势源于其最大的优势:一次编写,到处运行。Java 需要运行于虚拟机(即 JVM)之 上,为了保证 Java 字节码在各种 JVM 部署平台上运行效果一致,作些妥协是必须的.
虽然 Java 有一套完备的 I/O 类,但迄今 为止还只是针对通用特性,通常位于高端抽象层,横跨各种操作系统。这些 I/O 类主要面向流数 据,经常为了处理个别字节或字符,就要执行好几个对象层的方法调用。
传统Java I/O将不同的 I/O 对象组合到一起,提供了高度的灵活性,但需要处理 大量数据时,却可能对执行效率造成致命伤害。I/O 的终极目标是效率,而高效的 I/O 往往又无法 与对象形成一一对应的关系。高效的 I/O 往往意味着您要选择从 A 到 B 的最短路径,而执行大量 I/O 操作时,复杂性毁了执行效率。
当移动大量数据时,这些 I/O 类可 伸缩性不强,也没有提供当今大多数操作系统普遍具备的常用 I/O 功能,如文件锁定、非块 I/O、 就绪性选择和内存映射。这些特性对实现可伸缩性是至关重要的,对保持与非 Java 应用程序的正 常交互也可以说是必不可少的,尤其是在企业应用层面,而传统的 Java I/O 机制却没有模拟这些通用 I/O 服务。
Java 规范请求#51 (JSR 51, http://jcp.org/jsr/detail/51.jsp)包含了对高速、可伸缩 I/O 特性的详尽描述,借助这一特性,底层操作系统的 I/O 性能可以得到更好发挥, 这些促成了Java NIO的诞生。
随着 Merlin 的发布,操作系统强大的 I/O 特性终于可以借助 Java 提供的工具得到充分发挥。 论及 I/O 性能,Java 再也不逊于任何一款编程语言。
预备知识
1.缓冲区(Buffers)
新的Buffer类是常规Java类和通道之间的纽带。原始数据元素组成的固定长度数组,封装在包含状态信息的对象中,存入缓冲区。缓冲区提供了一个会合点:通道即可提取放在缓冲区中的数据, 也可以向缓冲区存入数据供读取。此外,还有一种特殊类型的缓冲区,用于内存映射文件。
2.通道(Channels)
NIO 新引入的最重要的抽象是通道的概念。Channel对象模拟了通道连接,通道既可以是单向的(进或出),也可以是双向的(进和出)。可以把通道想象成连接缓冲区和I/O服务的捷径。
3. 文件锁定和内存映射文件(File locking and memory-mapped files)
新的FileChannel类包含在java.nio.channels包内,提供了许多面向文件的新特性,其中最有趣的两个是文件锁定和内存映射文件。
在多个进程协同工作的情况下,要协调各个进程对共享数据的访问,文件锁定是必不可少的工 具。
将文件映射到内存,这样在您看来,磁盘上的文件数据就像是在内存中一样。这利用了操作系 统的虚拟内存功能,无需在内存中实际保留一份文件的拷贝,就可实现文件内容的动态高速缓存。
4. 套接字(Sockets)
套接字通道类为使用网络套接字实现交互提供了新方法。套接字通道可工作于非块模式,并可 与选择器一同使用。因此,多个套接字可实现多路传输,管理效率也比 java.net 提供的传统套 接字更高。
三个新套接字通道,即 ServerSocketChannel、SocketChannel 和 DatagramChannel。
5. 选择器(Selectors)
选择器可实现就绪性选择。 Selector 类提供了确定一或多个通道当前状态的机制。 使用选择 器,借助单一线程,就可对数量庞大的活动 I/O 通道实施监控和维护。
6. 字符集(Character sets)
java.nio.charsets 提供了新类用于处理字符与字节流之间的映射关系。您可以对字符转
换映射方式进行选择,也可以自己创建映射。
参考文献
- Java NIO (OReilly出版社)