讀古今文學網 > Java程序員修煉之道 > 2.1 Java I/O簡史 >

2.1 Java I/O簡史

要品出NIO.2 API設計的真正味道,並深刻理解它們的用法,應該先弄清Java I/O的歷史。但我們非常理解你想要接觸代碼的渴望。別著急,你的這種渴望可以在2.2節得到滿足。

如果你發現某些API的用法非常簡單甚至有點古怪,本節會幫助你從API設計者的角度看待NIO.2。這是Java I/O的第三個主要版本,所以讓我們回顧一下Java對I/O支持的發展歷史,看看NIO.2是怎麼產生的。

Java之所以能夠廣泛流傳,其強大、豐富、簡明的類庫功不可沒,編程時要解決的大多數問題幾乎都可以在其中找到支持。但經驗豐富的Java開發人員都知道,在老版本的Java中,有些地方不是那麼給力。曾經讓他們最崩潰的就是Java的輸入/輸出(I/O)API。

2.1.1 Java 1.0到1.3

在Java的早期版本(1.0~1.3)中沒有完整的I/O支持。也就是說開發人員在開發需要I/O支持的應用時,要面臨如下問題。

  • 沒有數據緩衝區或通道的概念,開發人員要編程處理很多底層細節。
  • I/O操作會被阻塞,擴展能力受限。
  • 所支持的字符集編碼有限,需要進行很多手工編碼工作來支持特定類型的硬件。
  • 不支持正則表達式,數據處理困難。

基本上,早期版本的Java缺乏對非阻塞I/O的支持。開發人員萬般無奈,只好自己實現可伸縮的I/O解決方案。在Java 1.4發佈之前,Java一直沒能在服務器端開發領域得到重用,我們認為主要原因就是缺乏對非阻塞I/O的支持。

2.1.2 在Java 1.4中引入的NIO

為了解決這些問題,Java開始實現對非阻塞I/O的支持,與其他I/O特性一起,幫助開發人員交付更快、更可靠的I/O解決方案。其中有兩次主要改進:

  • 在Java 1.4中引入非阻塞I/O;
  • 在Java 7中對非阻塞I/O進行修改。

2002年發佈Java 1.4時,非阻塞I/O(NIO)以JSR-51的身份加入到Java語言中。下面這些特性就是那時增加的。自此之後,Java語言終於得到了服務器端開發人員的青睞:

  • 為I/O操作抽像出緩衝區和通道層;
  • 字符集的編碼和解碼能力;
  • 提供了能夠將文件映射為內存數據的接口;
  • 實現非阻塞I/O的能力;
  • 基於流行的Perl實現的正則表達式類庫。

Perl——正則表達式之王

毋庸置疑,Perl編程語言是正則表達式處理之王。實際上,它的設計和實現相當出色,甚至很多編程語言(包括Java)競相模仿Perl的語法和語義。如果你對Perl語言感興趣,可以訪問http://www.perl.org/一探究竟。

NIO無疑使Java向前邁出了一大步,但I/O編程對Java開發人員來說仍然是個挑戰。特別是對於文件系統中的文件和目錄處理而言,支持力度還是不夠。那時的java.io.File類有些比較煩人的局限性。

  • 在不同的平台中對文件名的處理不一致。1
  • 沒有統一的文件屬性模型。(比如讀寫訪問模型)
  • 遍歷目錄困難。
  • 不能使用平台/操作系統的特性。2
  • 不支持文件系統的非阻塞操作。3

1 一些批評者會說Java沒有兌現「一次編寫,處處運行」的承諾。 2 人們通常希望能夠使用Linux/UNIX中的符號鏈接機制。 3 Java 1.4的確支持網絡套接字的非阻塞操作。

2.1.3 下一代I/O-NIO.2

為了突破這些局限性,同時也為了支持現代硬件和軟件I/O的新範例,由阿蘭‧波特曼主導的JSR-203應運而生。JSR-203最終變成了我們在Java 7中見到的NIO.2 API。它有三個主要目標,JSR-203規範中的第2.1節對它們進行了詳細的介紹(http://jcp.org/en/jsr/detail?id=203)。

  1. 一個能批量獲取文件屬性的文件系統接口,去掉和特定文件系統相關的API,還有一個用於引入標準文件系統實現的服務提供者接口。
  2. 提供一個套接字和文件都能夠進行異步(與輪詢、非阻塞相對)I/O操作的API。
  3. 完成JSR-51中定義的套接字——通道功能,包括額外對綁定、選項配置和多播數據報的支持。

接下來讓我們從新文件系統的基礎Path和它的朋友們開始吧!