Java NIO:前言

前言

计算机毫无用处,除了答案什么也没有。
——毕加索
本书介绍了 Java 平台上的高级输入/输出,具体点说,就是使用 Java 2 标准版(J2SE)软件
开发包(SDK)1.4 及以后版本进行的输入/输出。J2SE 1.4 版代号 Merlin,包含可观的 I/O 新特
性,对此我们将作详细论述。这些新的 I/O 特性主要包含在 java.nio 软件包及其子包中,并被命
名为 New I/O(NIO)。通过本书,您将学会如何使用这些令人兴奋的新特性来极大地提升 Java 应
用程序的 I/O 效率。
Java 真正的归宿还在企业应用(何谓“企业应用”,恐怕还没有一个确切的定义),但与本地编
译语言相比,Java 在 I/O 领域一直处于劣势,这种情况直到 J2SE SDK 发布了 1.4 版以后才有了改
观。Java 的劣势源于其最大的优势:一次编写,到处运行。Java 需要运行于虚拟机(即 JVM)之
上,为了保证 Java 字节码在各种 JVM 部署平台上运行效果一致,作些妥协是必须的。既然需要通
用于不同的操作系统平台,那么,某种程度上就必须选择各种平台都接受的处理方案。
最切实地感受到妥协带来的后果的,莫过于 I/O 领域。虽然 Java 有一套完备的 I/O 类,但迄今
为止还只是针对通用特性,通常位于高端抽象层,横跨各种操作系统。这些 I/O 类主要面向流数
据,经常为了处理个别字节或字符,就要执行好几个对象层的方法调用。
这种面向对象的处理方法,将不同的 I/O 对象组合到一起,提供了高度的灵活性,但需要处理
大量数据时,却可能对执行效率造成致命伤害。I/O 的终极目标是效率,而高效的 I/O 往往又无法
与对象形成一一对应的关系。高效的 I/O 往往意味着您要选择从 A 到 B 的最短路径,而执行大量
I/O 操作时,复杂性毁了执行效率。
传统 Java 平台上的 I/O 抽象工作良好,适应用途广泛。但是当移动大量数据时,这些 I/O 类可
伸缩性不强,也没有提供当今大多数操作系统普遍具备的常用 I/O 功能,如文件锁定、非块 I/O、
就绪性选择和内存映射。这些特性对实现可伸缩性是至关重要的,对保持与非 Java 应用程序的正
常交互也可以说是必不可少的,尤其是在企业应用层面,而传统的 Java I/O 机制却没有模拟这些通
用 I/O 服务。
具体的企业在具体的系统上配置具体的应用,这里无关乎抽象。在现实世界,效率是大事——
头等大事。企业购置的用于部署大型应用的计算机系统,其 I/O 性能异常卓越(系统供应商往往投
入巨资进行研发),而 Java 迄今为止一直无法充分利用这一点。当企业的需求是以最快的速度传
送大量数据时,样貌朴实但迅捷的解决方案往往胜过漂亮却动作迟缓的。总之一句话,时间就是金

JDK 1.4 是由 Java 社区进程(Java Community Process)主导发行的首个主要发行版。Java 产品
的用户和供应商可就 Java 平台需要引入什么新特性提出要求和建议,JCP(http://jcp.org/)为此提
供了手段。本书的主题——Java New I/O(NIO)——就是这样一项提议的产物。Java 规范请求#51
(JSR 51, http://jcp.org/jsr/detail/51.jsp)包含了对高速、可伸缩 I/O 特性的详尽描述,借助这一特
性,底层操作系统的 I/O 性能可以得到更好发挥。JSR 51 的实现,其结果就是新增类组合到一起,
构成了 java.nio 及其子包,以及 java.util.regex 软件包,同时现存软件包也相应作了几处
修改。JCP 网站详细介绍了 JSR 的运作流程,以及 NIO 从最初的提议到最终实现并发布的演进历
程。
随着 Merlin 的发布,操作系统强大的 I/O 特性终于可以借助 Java 提供的工具得到充分发挥。
论及 I/O 性能,Java 再也不逊于任何一款编程语言。

组织形式

本书分六章,每章针对 NIO 的一个大的方面。第一章讨论一般 I/O 概念,为以后各章相关论述
作了铺垫。第二至第四章论及 NIO 的核心内容:缓冲区、通道和选择器。接下来介绍新引入的正
则表达式 API。正则表达式的处理与 I/O 紧密贴合,亦被纳入 JSR 51 特征集之内。最后,我们看一
下新的可插拔字符集映射系统,这也是 NIO 和 JSR 51 的组成部分。
以下概要,是专门为那些迫不及待往前赶的人准备的。

缓冲区(Buffers)

新的 Buffer 类是常规 Java 类和通道之间的纽带。原始数据元素组成的固定长度数组,封装在
包含状态信息的对象中,存入缓冲区。缓冲区提供了一个会合点:通道既可提取放在缓冲区中的数
据(写),也可向缓冲区存入数据供读取(读)。此外,还有一种特殊类型的缓冲区,用于内存映
射文件。
第二章将详细讨论缓冲区对象。

通道(Channels)

NIO 新引入的最重要的抽象是通道的概念。Channel 对象模拟了通信连接,管道既可以是单向
的(进或出),也可以是双向的(进和出)。可以把通道想象成连接缓冲区和 I/O 服务的捷径。
某些情况下,软件包中的旧类可利用通道。为了能够向与文件或套接字关联的通道进行存取,
适当的地方都增加了新方法。
多数通道可工作在非块模式下,这意味着更好的可伸缩性,尤其是与选择器一同使用的时候。
通道会在第三章作详细介绍。

文件锁定和内存映射文件(File locking and memory-mapped files)

新的 FileChannel 对象包含在 java.nio.channels 软件包内,提供许多面向文件的新特
性,其中最有趣的两个是文件锁定和内存映射文件。
在多个进程协同工作的情况下,要协调各个进程对共享数据的访问,文件锁定是必不可少的工
具。
将文件映射到内存,这样在您看来,磁盘上的文件数据就像是在内存中一样。这利用了操作系
统的虚拟内存功能,无需在内存中实际保留一份文件的拷贝,就可实现文件内容的动态高速缓存。
文件锁定和内存映射文件也在第三章讨论。

套接字(Sockets)

套接字通道类为使用网络套接字实现交互提供了新方法。套接字通道可工作于非块模式,并可
与选择器一同使用。因此,多个套接字可实现多路传输,管理效率也比 java.net 提供的传统套
接字更高。
三个新套接字通道,即 ServerSocketChannel、SocketChannel 和 DatagramChannel,将在第三章
讲到。

选择器(Selectors)

选择器可实现就绪性选择。Selector 类提供了确定一或多个通道当前状态的机制。使用选择
器,借助单一线程,就可对数量庞大的活动 I/O 通道实施监控和维护。
选择器会在第四章作详细介绍。

正则表达式(Regular expressions)

新增的 java.util.regex 软件包将类似 Perl 语言的正则表达式处理机制引入 Java。这一人
们期盼已久的特性有着广泛用途。
新的正则表达式 API 之所以被看成是 NIO 的组成部分,是因 JSR 51 把它与其他 NIO 特性放在
一起作了详细说明。虽然它在许多方面与 NIO 的其他组成部分缺乏平行关系,但它在文件处理等
众多领域都是极其有用的。
第五章讨论 JDK 1.4 正则表达式 API。

字符集(Character sets)

java.nio.charsets 提供了新类用于处理字符与字节流之间的映射关系。您可以对字符转
换映射方式进行选择,也可以自己创建映射。
字符代码转换的相关问题在第六章讨论。

目标读者

本书为中高级 Java 程序员所写:他们熟练掌握这门语言,在完成大规模、复杂的数据处理任
务时,有充分利用 Java NIO 所提供之新特性的愿望和需求。在写作的过程中,我假定您对 JDK 标
准类软件包、面向对象的设计技巧、继承等等都有充分了解。我还假定您了解 I/O 在操作系统层面
的基本工作原理,知道什么是文件,什么是套接字,什么是虚拟内存,诸如此类。第一章就这些概
念作了高屋建瓴的回顾,但没有深度剖析。
如果您对 Java 平台上的 I/O 软件包尚处于摸索阶段,也许您应该先读一读 Elliote Rusty Harold
所著《Java I/O》(O'Reilly)(http://www.oreilly.com/catalog/javaio/)。那是一本关于 java.io 软
件包的很好的入门教材。虽然可以把本书看作那本书的后续读物,但两者并无承接关系。本书重点
关注的是如何利用新的 java.nio 软件包实现 I/O 性能的最大化。另外,本书还引入了一些新的
I/O 概念,这也超出了 java.io 软件包的范畴。
我们还探讨了字符集编码和正则表达式,这也是与 NIO 绑定在一起的新特征集的一部分。为
软件国际化或专业应用使用字符集的程序员会对 java.nio.charsets 软件包感兴趣,第六章会
有相关讨论。
如果您已转向 Java,但时不时地需要回到 Perl 处理正则表达式,告诉您,以后再也不用了。新
推出的 java.util.regex 软件包在标准 JDK 中包含了 Perl 5 所有的正则表达式功能,个别极其
晦涩难懂的除外,此外还有几项创新。

软件及版本

本书描述了 Java 的 I/O 性能,尤其是 java.nio 和 java.util.regex 两个软件包。这两个
软件包首次出现于 J2SE 1.4 版,所以,您必须拥有 Java SDK 1.4(或以后)的可用版本,才能使用
本书提供的素材。您可通过访问 Sun 公司网站 http://java.sun.com/j2se/1.4/获得 Java SDK。我还会在
正文中使用 J2SE SDK 指代 Java 开发包(JDK),在本书范围内,二者含义相同。
本书基于 2002 年 2 月发布的 SDK 最终版本 1.4.0。早前几个月,1.4 beta 版已广为流传。在最
终版本即将发布之前,NIO API 作了重要修正。因此,您会发现本书所讲某些细节,与您在最终版
本发布之前所知论述存在出入。本书根据所有已知的最后修正作了更新,应该不存在与最终版本
1.4.0 不一致之处。J2SE 的后续版本可能引入与本书相冲突的内容,如果存在疑问,请参考与软件
一同发布的技术文档。

本书包含众多实例,向 您 示范如何使用 API 。所有代码举例及相关信息都可从
http://www.javanio.info/下载,更多实例和测试代码也可从该网站取得。NIO 执行小组提供的额外代
码示例可从 http://java.sun.com/j2se/1.4/docs/guide/nio/example/取得。
本书中使用的约定
像所有程序员一样,我对代码的排版样式也有宗教般的虔诚。本书所举范例系根据我个人喜好
进行的排版,在相当程度上也符合惯例。我信奉的标准是,一个制表符缩进八格,外加大量的空白
分隔符。有些代码举例迫于空间有限,把缩进减少到四格。网站上供下载的源代码使用制表符产生
缩进。
当我就 API 举例,展示 JDK 中某个类的方法列表时,我一般只列出上下文提到的特定方法,
而把无关方法略去。我通常在章节的开头提供完整的 API 列表,而在随后的具体讨论环节列出其子
集。
这些 API 示例通常在语法上并不正确,只是若干方法签名的片段,没有方法主体,仅用于列举
可用方法及认可参数。例如:
 

public class Foo
{ 
 public static final int MODE_ABC
 public static final int MODE_XYZ
 public abstract void baz (Blather blather);
 public int blah (Bar bar, Bop bop)
} 

 本例中,方法 baz( )在语法上是完整的,因为抽象声明只包含签名。但 blah( )缺少分号,暗示
在该类定义中应当有方法主体跟随其后。当我罗列公共域定义常数,如 MODE_ABC 和 MODE_XYZ
的时候,有意省略了初始值,因为省去的信息不重要。既然定义了公共名,就可以在不知道值的情
况下使用该常数。
只要有可能,我尽量直接从随 1.4 JDK 分发的代码截取 API 信息。我着手写作本书的时候,
JDK 的版本是 1.4 beta 2。为了保证代码片段是最新的,我尽了一切努力,如有疏漏,在此表示歉
意,JDK 提供的源代码才是最终权威

字体约定
本书采用 O'Reilly 标准字体约定,这并非完全出于个人选择。本书手稿直接以 XML 格式创
作,使用纯 Java GUI 编辑器(XXE,http://www.xmlmind.com/)。该软件强制使用 DTD I 及
O'Reilly 的 DocBook 子集,因此,我从未指定字体或字形。我可以选择 XML 元素,如

<filename>或<programlisting>,然后 O'Reilly 的排版软件会采用合适的字形。
读者当然不必关心这些。那么,以下就是本书所用字体约定的简要说明:
Italic(斜体)用于:
• 路径名、文件名和程序名
• 互联网地址,如域名、URL
• 新术语及其定义
Constant Width(等宽字体)用于:
• Java 代码中的名称和关键字,包括方法名、变量名和类名
• 程序清单和代码片段
• 常数值
Constant Width Bold(等宽粗体)用于:
• 强调代码示例的重点部分
如何联系我们
我虽不是头回写书,却是头回为一般出版物而写。写书可比读书难多了,要解释清楚和 Java
有关的命题,尤其让人心生恐惧,因为 Java 涉及面广,发展迅速,还有为数众多聪明绝顶的人
士,芝麻大点的错误也能指出来。
任何意见,不管是正面的还是负面的,我都愿意倾听。我自信在这个项目上做足了功课,但错
误在所难免。有关本书组织结构和内容安排的建设性意见,我尤其感兴趣。我力求本书条理清晰、
布局合理,也力求有完备的交叉引用,为在各章节随意跳转提供便利。
报酬丰厚的顾问合同、演讲邀约以及任何免费资料,我都欢迎。无聊邮件、垃圾邮件,我将一
笑置之。
通过邮箱 ron@javanio.info,或者登陆 http://www.javanio.info/,都可与我取得联系。
这个图标表示提示、建议或概括性的说明。
这个图标表示一个警告或者注意事项提醒。

O'Reilly 及我本人已竭尽所能对书中信息进行了核实,但某些特性可能已发生改变(抑或我们
确有谬误!),不管各位发现什么错误,或者对未来版本有任何建议,都请一并告知。信可写到:
O'Reilly & Associates, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
(800) 998-9938(美国及加拿大)
(707) 829-0515(国际/当地)
(707) 829-0104(传真)
您还可通过电邮与 O'Reilly 取得联系。订阅邮件或索取目录,发个消息到:
info@oreilly.com
我们为本书设立了网页,勘误表、示例及任何补充信息都在上面。网址为:
http://www.oreilly.com/catalog/javanio/
询问技术问题,或发表评论,发邮件到:
bookquestions@oreilly.com
欲了解与 O'Reilly 图书、会议、资源中心及 O'Reilly 网络有关的更多信息,留意 O'Reilly 网
站:
http://www.oreilly.com/
鸣谢
攒一本书出来可不轻松,哪怕是像本书这样的中小部头。因此,我要向在本书写作过程中给予
我帮助的几位朋友表示感谢。
首先,我要感谢本书编辑 Mike Loukides,为我提供了加入 O'Reilly 作家队伍的机会。我是如何
赢得 O'Reilly 的出书合同的,至今都觉得不可思议。那是一份荣耀,也是一份责任。谢谢,Mike,
逗号用得不对,还请见谅。
我还要感谢 Bob Eckstein 和 Kyle Hart(也是 O'Reilly 的),感谢 Bob 在本书最初的几稿给予我
的帮助,感谢 Kyle 给我提供了 JavaOne 年会的免费资料(对了,那次市场营销没准也帮助不
小)。Jessamyn Read 把我的涂鸦变成了专业图表。我还要感谢多产的 David Flanagan,在他的
《Java 技术手册》(第四版)(Java in a Nutshell, Fourth Edition [O'Reilly])中提及了我微不足道的
贡献,并允许我使用该书中的正则表达式语法表。

 

 

 

 

 

转载于:https://my.oschina.net/LucasZhu/blog/1606713

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值