Java NIO(New IO) 還是在 JDK 1.4 中引入的新特性。JDK 1.4 的另一重要特性Regex大家應該經常用到,但 NIO 就可能使用寥寥了,大概是緣於舊有 IO 體系仍然夠用。有如 JDK1.5 早就泛型和註解了,但基於各種原因而無法親力去實踐泛型和註解一般,NIO 多數時候也只是與我們擦著肩而已。
相比與 Old IO,NIO 在某些領域裡確有其過人之處,所以現在讓我們一起來對 NIO 有個更楚的認識。
NIO 的相關 API,在 java.nio 中,它會與你糾纏的就是各種 Channel 和 Buffer。相關的應用在於處理通道和緩衝區、非同步(非阻塞)的 IO、檔案的鎖定、字元集的處理上。
Channel 可以通過調用 FileInputStream、FileOutputStream、RandomAccessFile、DatagramSocket、ServerSocket 和 Socket 的 getChannel() 方法獲得。Channel 有點像舊 I/O 的流,舊 I/O 的讀寫操作可以在流上直接進行,而 NIO 都是在各種 Buffer 上讀寫資料。
由於使用了專屬的通道和緩衝區,相比舊有的 IO 流處理的是位元組流(流 IO),NIO 所使用的方式是塊 I/O,所以在大塊資料處理時塊 I/O 比流 I/O 效率要高。NIO 在一定程度上相當於用本地代碼來處理了 I/O 操作。
非同步 I/O 使得你在進行網路傳輸時,無需像原來那樣 read()/write() 來阻塞線程來等待資料的到來和直至寫完資料。NIO 的方式是註冊監聽器來監聽通道上的事件,在一個線程上就能流暢的處理 Socket 通訊。不像舊 I/O 必須求助於輪詢並建立許許多多的線程來處理大量的串連。
例如,基於 NIO 的組件有,網路應用程式框架 Apache MINA,Memcached 用戶端 XMemcached,Socket 應用組件 xSocket,還有 Tomcat 6 也支援使用 NIO 的 connector 了。
檔案鎖使得 Java 程式也可以對整個檔案或檔案的部分進行獨佔(排它)或共用的讀或寫,防止了不同的進程對同一個檔案的幹擾。不過在不同的作系統下的行為可能會有細微的差異。檔案鎖(Lock)可以通過 Channel 的 lock() 或 tryLock() 獲得,Channel 的 release() 方法或關閉通道時即釋放了鎖。
另外,NIO 可以更好的使用控制字元集。
與 NIO 還有一個很重要的 Buffer 就是記憶體對應檔--通過調用 FileChannel 類的 map() 方法可獲得 MappedByteBuffer,此記憶體對應檔與 Windows 下的記憶體映射有相似性,又不盡然,Windows 下的記憶體對應檔可用來在不同的進程間共用資料,Java 的這個東西要細究下。
以上本就是泛泛而語,初識者或會覺得不知所云,也無甚味可解,原本就是對 Java NIO 的粗獷的理解,雜亂而無序。
在 IBM DeveloperWorks 上有一個 Java NIO 入門教程,https://www6.software.ibm.com/developerworks/cn/education/java/j-nio/tutorial/index.html,為了便於學習和分享,特製作成了一個 chm 檔案:NIO 入門.chm.rar。
參考資料:1. 基於事件的NIO多線程伺服器
2. Servlet API 和 NIO: 最終組合在一起
3. Java NIO原理和使用
4. 使用Java NIO編寫高效能的伺服器
5. Java NIO API詳解
6. nio檔案讀寫