1. 程式人生 > >Java網路程式設計(三) java 流io和塊io

Java網路程式設計(三) java 流io和塊io

在 Java 的早期,JVM 在解釋位元組碼時往往很少或沒有執行時優化。這就意味著,Java 程式往往拖得很長,其執行速率大大低於本地編譯程式碼,因而對作業系統I/O 子系統的要求並不太高。 如今在執行時優化方面,JVM 已然前進了一大步。現在 JVM 執行位元組碼的速率已經接近本地編譯程式碼,藉助動態執行時優化,其表現甚至還有所超越。這就意味著,多數 Java 應用程式已不再受 CPU 的束縛(把大量時間用在執行程式碼上),而更多時候是受 I/O 的束縛(等待資料傳輸)。 

       然而,在大多數情況下,Java 應用程式並非真的受著 I/O 的束縛。作業系統並非不能快速傳送資料,讓 Java 有事可做;相反,是 JVM 自身在 I/O 方面效率欠佳。作業系統與 Java 基於流的 I/O模型有些不匹配。
作業系統要移動的是大塊資料(緩衝區),這往往是在硬體直接儲存器存取(DMA)的協助下完成的。而 JVM 的 I/O 類喜歡操作小塊資料——單個位元組、幾行文字。結果,作業系統送來整緩衝區的資料,java.io 的流資料類再花大量時間把它們拆成小塊,往往拷貝一個小塊就要往返於幾層物件。作業系統喜歡整卡車地運來資料,java.io 類則喜歡一鏟子一鏟子地加工資料。有了 NIO,就可以輕鬆地把一卡車資料備份到您能直接使用的地方(ByteBuffer 物件)。 

1)面向流I/O的系統:一次處理一個位元組的資料。一個輸入流每次會讀入一個位元組的資料,一個輸出流同樣每次次消費一個位元組的資料。對於流式資料,很容易建立過濾器。可以相對簡單地把幾個過濾器連線在一起,每個過濾器完成自己的工作,也是按位元組進行過濾,精細的處理機制。另一方面,面向流I/-O的通訊往往比較緩慢。 

2)面向塊I/O的系統:
以塊為單位處理資料。每個操作步驟會生成或消費一個塊的資料。以塊為單位處理資料,其處理速度遠快於以位元組流為單位的方式。但是,與面向流I/O的通訊相比,面向塊I/O的通訊缺乏優雅和簡潔。 

      新的抽象把重點放在瞭如何縮短抽象與現實之間的距離上面。NIO 抽象與現實中存在的實體有著非常真實直接的互動關係。 

關於何時該採用傳統io,何時應該採用nio: 
1) 擴充套件性考慮:例如在進行Socket程式設計通訊時每一個Socket都應占據一個執行緒。使用NIO雖然更富有效率,但相對難以編碼和擴充套件。(當然這一現象在不斷的被新的設計和NIO庫的特性所改善) 
2) 效能考慮:在處理成千上萬的連線時,你可能需要更好的傳統IO的擴充套件性;但是如果連線數量較低時,你可能更注重NIO的高吞吐率。 
3) 當使用SSL (Secure Sockets Layer,安全套接字層) 工作時,選擇NIO則實現難度很大