1. 程式人生 > >java讀寫檔案時nio、bio對比

java讀寫檔案時nio、bio對比

1.   基本 概念
     IO 是主存和外部裝置 ( 硬碟、終端和網路等 ) 拷貝資料的過程。 IO 是作業系統的底層功能實現,底層通過 I/O 指令進行完成。所有語言執行時系統提供執行 I/O 較高級別的工具。 (c 的 printf scanf,java 的面向物件封裝 )
2.    Java 標準 io 回顧
      Java 標準 IO 類庫是 io 面向物件的一種抽象。基於本地方法的底層實現,我們無須關注底層實現。 InputStream\OutputStream( 位元組流 ) :一次傳送一個位元組。 Reader\Writer( 字元流 ) :一次一個字元。

3.    nio 簡介

      niojava New IO的簡稱,在jdk1.4裡提供的新apiSun官方標榜的特性如下:
–     為所有的原始型別提供 (Buffer) 快取支援。
–     字符集編碼解碼解決方案。
–     Channel :一個新的原始 I/O 抽象。
–     支援鎖和記憶體對映檔案的檔案訪問介面。
–     提供多路 (non-bloking) 非阻塞式的高伸縮性網路 I/O 。
本文將圍繞這幾個特性進行學習和介紹。

4.   Buffer&Chanel
     ChannelbufferNIO是兩個最基本的資料型別抽象。
     Buffer:
–        是一塊連續的記憶體塊。

–       是 NIO 資料讀或寫的中轉地。
Channel:
–       資料的源頭或者資料的目的地
–       用於向 buffer 提供資料或者讀取 buffer 資料 ,buffer 物件的唯一介面。

–      非同步 I/O 支援

         java原來的I/O體系中, I/O實際上是以Stream(流)這個抽象概念被使用,所有的I/O實際上被看做是單個位元組一個位元組一個位元組的移動; Stream I/O被用來和外界世界互動,在內部它用來將物件轉為bytes位元組流,然後再轉為物件;

         NIO的角色和目標實際上和原來的I/O是相同的,但是它使用了一個不同的抽象概念:block I/O. 正如你將所見到的那樣,block I/O比原來的I/O有效率得多;

Streams和blocks的對比

         原來的I/O包和NIO處理資料最大的不同之處在於資料打包(packaged)和傳輸(transmitted)的方式。正如前面所提到的那樣,IO(java.io.*)是以流的方式處理資料的,而NIO是以blocks(塊)的方式來處理資料的.

         一個流面向(stream-oriented)的I/O系統在處理資料時是一次只處理一個位元組;作為input的stream一次向計算機生產一個byte,作為output的stream一次向計算機要求消費一個byte(計算機生產byte),對stream建立filter是一件非常容易的事情,同時如果你希望通過chain模式將幾個filter連在一起也很容易,最終可以將大量複雜的處理分成一個簡單,巧妙的處理模式;但是同時,stream-oriented的I/O處理通常非常低效率。

         而一個塊面向(block-oriented)的I/O系統成塊的處理資料,每次操作都會生產或者消費以block為單位的資料;所以,這種方式會比stream-oriented的處理方式高效地多,但是block-oriented的I/O也缺少以stream-oriented程式設計時的簡單和優雅;


什麼是buffer?:

         當資料寫入或者資料讀取時,這些資料被儲存在一個buffer物件中;buffer物件是nio和原io包中一個最重要的區別。在原來的io系統中,資料的讀取和獲得是首先通過Stream流物件。

         在nio中,所有的資料採用buffers的方式進行處理。當資料被讀取的時候,讀入資料被先儲存到buffer中;資料寫入的時候,寫入資料也首先放置到buffer中。

         一個buffer物件實際上是一個array物件,但是又不單單隻具有array的功能;一個buffer物件提供了結構化訪問資料的能力,並且記錄了系統讀/寫操作的日誌。

buffer的型別?:

         最常見的使用buffer的方式是ByteBuffer,一個ByteBuffer的底層陣列允許get/set  buffers的操作;

         其他的buffer型別包括:CharBuffer,ShotBuffer,

 IntBuffer, LongBuffer, DoubleBuffer,FloatBuffer;

         每一種buffer的型別都是一個buffer介面;這些介面的行為除了處理的資料不同之外, 操作行為非常相似; 不過因為ByteBuffer被用來和大多數標準的I/O操作,所以除了共有的buffer操作之外,還有一些特別的操作行為;

什麼是channel?:

         一個Channel是一個可以操作讀寫資料的物件,channel的概念類似於io包中的stream(流)概念;

         如前所述,在nio中,所有的資料是通過buffer這個物件進行處理的;在讀寫資料的時候,你永遠不需要直接地操作Channel物件;

channel的型別?:

         和io中流(Stream)概念不同的是,channel是雙向的;一個流必須是InputStream或者OutputStream的子類,一個Channel可以是讀/寫操作的任何一種或兩種;因為channel的雙向特性,和流比起來更真實地反映了os的底層,尤其在Unix中。