天天看點

Java IO 之 FileInputStream & FileOutputStream源碼分析一、引子二、FileInputStream源碼分析三、FileOutputStream 源碼分析四、使用案例五、思考與小結

檔案,作為常見的資料源。關于操作檔案的位元組流就是 — fileinputstream & fileoutputstream。它們是basic io位元組流中重要的實作類。

fileinputstream源碼如下:

1. 三個核心方法

三個核心方法,也就是override(重寫)了抽象類inputstream的read方法。

int read() 方法,即

代碼實作中很簡單,一個try中調用本地native的read0()方法,直接從檔案輸入流中讀取一個位元組。iotrace.filereadend(),字面意思是防止檔案沒有關閉讀的通道,導緻讀檔案失敗,一直開着讀的通道,會造成記憶體洩露。

int read(byte b[]) 方法,即

代碼實作也是比較簡單的,也是一個try中調用本地native的readbytes()方法,直接從檔案輸入流中讀取最多b.length個位元組到byte數組b中。

int read(byte b[], int off, int len) 方法,即

代碼實作和 int read(byte b[])方法 一樣,直接從檔案輸入流中讀取最多len個位元組到byte數組b中。

可是這裡有個問答: q: 為什麼 int read(byte b[]) 方法需要自己獨立實作呢? 直接調用 int read(byte b[], int off, int len) 方法,即read(b , 0 , b.length),等價于read(b)? a:待完善,希望路過大神回答。。。。向下相容?? finally??

2. 值得一提的native方法

上面核心方法中為什麼實作簡單,因為工作量都在native方法裡面,即jvm裡面實作了。native倒是不少一一列舉吧:

native void open(string name) // 打開檔案,為了下一步讀取檔案内容 native int read0() // 從檔案輸入流中讀取一個位元組 native int readbytes(byte b[], int off, int len) // 從檔案輸入流中讀取,從off句柄開始的len個位元組,并存儲至b位元組數組内。 native void close0() // 關閉該檔案輸入流及涉及的資源,比如說如果該檔案輸入流的filechannel對被擷取後,需要對filechannel進行close。

其他還有值得一提的就是,在jdk1.4中,新增了nio包,優化了一些io處理的速度,是以在fileinputstream和fileoutputstream中新增了filechannel getchannel()的方法。即擷取與該檔案輸入流相關的 java.nio.channels.filechannel對象。

fileoutputstream 源碼如下:

三個核心方法,也就是override(重寫)了抽象類outputstream的write方法。

void write(int b) 方法,即

代碼實作中很簡單,一個try中調用本地native的write()方法,直接将指定的位元組b寫入檔案輸出流。iotrace.filereadend()的意思和上面fileinputstream意思一緻。

void write(byte b[]) 方法,即

代碼實作也是比較簡單的,也是一個try中調用本地native的writebytes()方法,直接将指定的位元組數組寫入該檔案輸入流。

void write(byte b[], int off, int len) 方法,即

代碼實作和 void write(byte b[]) 方法 一樣,直接将指定的位元組數組寫入該檔案輸入流。

native void write(int b, boolean append) // 直接将指定的位元組b寫入檔案輸出流 native native void writebytes(byte b[], int off, int len, boolean append) // 直接将指定的位元組數組寫入該檔案輸入流。

相似之處:

其實到這裡,該想一想。兩個源碼實作很相似,而且native方法也很相似。其實不能說“相似”,應該以“對應”來概括它們。 它們是一組,是一根吸管的兩個孔的關系:“一個input一個output”。 休息一下吧~ 看看小廣告:

下面先看代碼:

運作後,會發現根目錄中出現了一個“data.txt”檔案,内容為上面的代碼。

1. 簡單地分析下源碼:

1、建立了fileinputstream,讀取該代碼檔案為檔案輸入流。 2、建立了fileoutputstream,作為檔案輸出流,輸出至data.txt檔案。 3、針對流的位元組數組,一個 read ,一個write,完成讀取和寫入。 4、關閉流

2. 代碼調用的流程如圖所示:

Java IO 之 FileInputStream & FileOutputStream源碼分析一、引子二、FileInputStream源碼分析三、FileOutputStream 源碼分析四、使用案例五、思考與小結

3. 代碼雖簡單,但是有點小問題:

fileinputstream.available() 是傳回流中的估計剩餘位元組數。是以一般不會用此方法。 一般做法,比如建立一個 byte數組,大小1k。然後read至其傳回值不為-1,一直讀取即可。邊讀邊寫。

fileinputstream & fileoutputstream 是一對來自 inputstream和outputstream的實作類。用于本地檔案讀寫(二進制格式按順序讀寫)。

本文小結:

1、fileinputstream 源碼分析 2、fileoutputstream 資源分析 3、fileinputstream & fileoutputstream 使用案例 4、其源碼調用過程 歡迎點選我的部落格及github — 部落格提供rss訂閱哦!