Elliotte Rusty Harold
本文译自 O'Reilly 美国总公司网站上的文章,
不要再以为 Java 只能拿来设计网页上的动态图形,其实 Java 是一个功能完备的程式语言,而且是当今许多程式员的第一选择。因为 Java 语言具备清晰的架构、提供动态记忆体管理、 浑然天成地整合了 Web … 等优点,使得 Java 开发程式过程所需要的时间较许多其他开发工具少得多。 畅销作家 Elliotte Rusty Harold 最近出版的 一本书《 Java I/O 》 详细地带我们深入了解 Java I/O 的内部奥妙及其用法。我们特地邀请他接受我们几分钟的访谈, 针对 Sun 公司所规划的 Java I/O 的方向。
Wayner:哪一类的 Java 程式员该对 Java I/O 相关议题感兴趣?
Harold:所有的 Java 程式员都该对 Java I/O 感兴趣。几乎所有的程式多多少少都会牵涉到 I/O, 尽管其目的各有千秋。然而教科书上的 IO 范例常常只局限在命令列参数(command line arguments)和 System.out.println(),却忽略了真正的程式常需要读写档案、读写网路、资料加密解密、从串列埠 (serial port)收送资料、和资料库沟通 … 等。我们通常可以透过观察程式员驾驭 I/O 的能力 来判断他的专业程度,离 System.out.println() 越远的程式员程度越专业。
Wayner:在许多人既定的印象中,Java 是用来写网页上 applet 的工具,但其实 Java 是一个功能完整的程式语言。你认为 Java 和 C++ 此二功能完整的程式语言在 I/O 方面的比较上如何 ?
Harold:毫无疑问地,Java 的 I/O 工具比 C/C++ 更加洗练、强大、且容易使用。 C/C++ 以及其他许多语言都假定读写的资料来自 1970 年代的阳春终端机之类的设备, 跟不上时代的脚步,现代的 C/C++ 程式员也就深为此所苦。Java 是第一个抛弃此包袱的主流程式语言。Java 的设计者 早就意识到档案的读写、网路的连结、以及和串列埠的沟通相当重要,绝非资讯系一年级 学生的程式作业「读入一个数目,输出开根号的值」可以比拟的。
可惜的是,因为 Java I/O 所采行的结构相当不同於以往,使得许多程式员不知道它其实 很简单却也很强大。从我的学生们的反应、许多网路讨论区、以及邮寄讨论信件中,我发现 大多数的人一开始就问了不该问的问题。比方说,常有人问如何从 console 读取一个数字。 其实,他们不应该一开始就和 console 打交道。
学生总是在问 Java 有没有和 C 的 scanf() 类似的用法,我觉得这都要责怪教授没有好好教。 你瞧瞧,市面上一堆介绍 Java 的书时常一开始就教读者如何用 Java 写出等同於 C 的 scanf() 和 printf() 等功能。 我觉得这个现象背後的因素可能为:「作者根本不了解 Java,特别是 Java I/O」,或者「作者直接 沿用二十年不变的 Pascal 陈年旧例,懒得花心思改写」。现在已经是 1999 年了,使用者介面应该是 图形模式( GUI)而非文字模式( console )。我们有必要在资讯系的课程中向学生介绍现代化的 GUI 程式设计方式。 现在,我正在教研究生 Java 入门课程,班上的学生中不超过百分之十有 GUI 程式设计经验。
当然,使用者介面是 GUI,不表示传统的 I/O 方式不再重要。但是一旦你弃 console 不用, 你可以设计出更清楚的 I/O 介面,可轻易地支援档案、网路 … 等,使用 Java 就有这样的好处。
Wayner:至於那些 Web 的 applet 设计者来说,Java I/O 对他们有何影响呢?
Harold:Java 的安全机制严格地限制了网页浏览器内的 applet 所能进行的 I/O 动作。 目前主要的浏览器尚未支援 Java 2 的安全模型,所以纯粹只是「理论上可以, 实际上不行」。而且,大多数使用者不会因为希望网站设计人员较轻松就额外放宽 applet 的权限。 所以,一般 applet 使用到的 I/O 主要是和原伺服器之间建立网路连线、或使用 object serialization、 或 RMI。
Wayner:当微软开始建立自己的 Java 分枝时,它不用 RMI 而改采自己的方式,你对此的看法如何?
Harold:微软不用 RMI 是因为他们自己有一套 Windows 专属的技术 DCOM,微软也建立了 ActiveX 网页内嵌动态内容的技术来和 Java 一别苗头。但是不管 DCOM 或 ActiveX,都没有在 Web 设计的市场上 有所斩获,而且微软也为了利益和某些目的而放弃了它们。事实上 RMI 和底层的 object serialization 机制实在慢得可怕,而且元凶就是於 Java 本身。我所接触到的多数大型、非 applet 专案都是选用 CORBA,而非微软的 DCOM 或 Java 的 RMI。
Wayner:你认为 NC 有没有希望能以 applet 的方式下载软体回来 执行?在新版的 Java 2 中有没有这个可能?
Harold:如果此事成真,也不会是在 PC 或任何电脑平台上。电视游乐器或视讯接收盒(set-top box) 是更适合此方式的平台。
Wayner:Sun 透过 Unicode 对於多文化多语言的支援是否已经足够? 或只是聊备一格?
Harold:从 Java 1.1 开始,Java I/O 类别就已经完全支援国际化。主要的问题在於程式员对此 尚不甚熟悉,因为他们老是用不支援国际化的程式语言( 比方说 C 或 Pascal )的思考方式强套在 Java I/O 上,其实两者之间不相契合。一旦你了解在 Java 中不同国家的语言之间如何逻辑地切割功能,并知悉 他们的连接方式,使用起来就易如反掌,但如果你用别的程式语言想达到同样的目的,你会发现复杂到 难以掌控。
Wayner:有没有什么 I/O 的功能 Sun 还需要加强或扩充的?
Harold:目前 Java 不支援位元组格式「由小到大( little endian)」的资料,或其它次序的数值 (比方说 VAX 的浮点数)。但是,我在《 Java I/O 》一书设计了一些类别来告诉读者如何读写特殊格式 的资料到资料流( stream )。这些类别也可以和标准资料流轻易地相互连接。
Wayner:你认为 Java 需要支援更多的编码法吗?
Harold:很明显地,我们需要 Java 支援新的 Latin-0 字集来包含欧元符号。而且 Unicode 3.0 再几个月就要出炉了,Java 也需要在幕後做一些对应的微调,这样的动作不可影响到大多数现有的程式。 而且 IBM 宣称 Sun 把 EBCDIC 转换码搞乱了,这一点也要改进(我个人认为这是 IBM 的错,如果当初 他们有费点心思把 EBCDIC 标准化且整理好其文件,今天 EBCDIC 就不会这样混乱了)。除了上面的问题 之外, Sun 其实在支援大多数的字集上做得不赖。
Wayner:许多人抱怨不同公司的 Java 环境上有不少差异,你有没有发现什么严重的问题肇因於此?有什么地方我们应该注意的?
Harold: I/O 最大的问题在 java.io.File。虽然在 Java 2 已有改进,但仍显露出它的 Unix 血统。 java.io.File 在 Unix 上运作得很好,在 Windows 上还可以,但在 Mac 上不忍卒睹, 因为 java.io.File 对 「档案是什么」和「档名应该如何」做了许多简化性的假设,偏偏这些加假设中 有许多是只相容於 Unix 环境,而不适用在非 Unix 平台。还有一些潜在的问题, 比方说: Sun 认定只要是不可在档名中出现的两个任意分隔字元就可以 分别当作档名的分隔符号以及路径的分隔符号,这样的假设和 Mac 会产生冲突,对於 Mac 来说, 只有一个字元不能当作档名的一部份。这使得 Java 移植到 Apple 电脑上时需要一些罗唆的步骤。
Wayner:最後一个问题:你认为 Sun 在让 Java 跨平台这方面是不是做得不错?或者你认为有某些地方太过於 Unix 化?
Harold:对於跨平台来说, AWT 是一大麻烦。我知道设计一个能跨越 Windows、Mac、以及 Motif 的 GUI 类别库是相当困难的事,但 Sun 根本连试都没试。不过在 Java 2 和 Swing 问世後, 情况已经好转。虽然已经有改进了,但 Java 在这方面还是很蹩脚,因为它出自许多 Unix 程式员之手, 而且这些人对 Windows 和 Mac 所知不多。
Java 网路 API(比方说: java.net.Socket、 java.net.ServerSocket)也相当 Unix 化。 但其实 Windows 和 Mac 在网路的部分也很像 Unix,所以,在 Java 网路 API 上,倒不是很容易察觉 Unix 风味。
--------------------------------------------------------------------------------