1. 程式人生 > >深入分析Java I/O的工作機制 (一)

深入分析Java I/O的工作機制 (一)

此篇部落格看至許令波的深入分析javaWeb內幕書籍, 此篇部落格寫的是自己看完之後理解的重點內容,加一些理解,希望對你有幫助。

1.Java的I/O類庫的基本架構

先說一下什麼是類庫:可以說是類的集合,類庫包括介面、抽象類、具體類等。

I/O是機器獲取和互動資訊的主要渠道。 java在I/O上也一直在做持續的優化,在1.4版開始引入了NIO,提升了I/O的效能。

java的I/O操作類在包java.io下,大概有80個類左右,這些類大概可以分為如下4組:

  基於位元組操作的I/O介面:InputStream和OutputStream  (位元組是電腦儲存資訊的最小單位,字元比位元組大,一般我們操作的資料都是字元形式的。)

  基於字元操作的I/O介面:Writer和Reader

  基於磁碟操作的I/O介面:File

  基於網路操作的I/O介面:Socket

前兩組主要是傳輸資料的資料格式,後兩組主要是傳輸資料的方式,雖然Socket類並不在java.io包下,但是我仍然要把它們劃分在一起,因為我個人認為I/O的核心問題要麼是資料格式影響I/O操作,要麼是傳輸方式影響I/O操作,也就是將什麼樣的資料寫到什麼地方的問題。

 

1.1基於位元組的I/O操作介面

基於位元組的I/O操作介面輸入和輸出分別是InputStream和OutputStream

InputStream的類層次結構圖(OutputStream,Writer和Reader的類層次結構圖和InputStream差不多都是有很多子類可以實現不同的功能,他們的子類也相仿。):

看到這個結構圖其實只想說明兩點,一是操作資料的方式可以組合使用的,如這樣組合:

  

 OutputStream outputStream=new FileOutputStream("");//OutputStream可以new他的子類用於實現不同的作用。

小tip:父類作為接收型別,去new子類,稱為向上轉型。   子類作為接收型別,去new父類,稱為向下轉型。

 OutputStream outputStream=new FileOutputStream("");//父類 new子類  向上轉型
     BufferedOutputStream bufferedOutputStream= new
FileOutputStream("");//子類new父類 向下轉型

二是必須要指定流最終寫到什麼地方,要麼是寫到磁碟,要麼是寫到網路中,其實從上面的類層次結構圖中可以發現,寫網路實際上也是寫檔案,只不過寫網路還有一步需要處理,就是讓底層作業系統再將資料傳送到其他地方而不是本地磁碟。在後面詳細介紹網路I/O和磁碟I/O。

 

1.2基於字元的I/O操作介面

不管是磁碟還是網路傳輸,最小的儲存單元都是位元組,而不是字元,所有I/O操作的都是位元組而不是字元,但是為什麼要有操作字元的I/O介面呢?因為在我們程式中通常操作的資料都是字元形式的,為了操作方便當然要提供一個直接寫字元的I/O介面,如此而已。我們知道從字元到位元組必須要經過編碼轉換,而這個編碼又非常耗時,而且還會經常出現亂碼問題,所以I/O的編碼問題經常是讓人頭疼的問題。

Writer類提供了一個抽象方法write(char cbuf[], int off, int len)。

abstract public void write(char cbuf[], int off, int len) throws IOException;

Reader也提供了一個抽象方法read(char cbuf[], int off, int len),返回讀到的n個位元組數,不管是Writer耗時Reader類,它們都只定義了讀取或寫入的資料字元的方式也就是怎麼寫或讀,但是並沒有規定資料要寫在哪裡,這些內容就是後面要討論的基於磁碟和網路的工作機制。

abstract public int read(char cbuf[], int off, int len) throws IOException;

 

1.3位元組與字元的轉化介面

資料持久化或網路傳輸都是以位元組進行的,所以必須要有從字元到位元組或從位元組到字元的轉化,從字元到位元組需要轉化,其中讀的轉化過程如下:

InputStreamReader類是從位元組到字元的轉化橋樑,

 

 從InputStream到Reader的過程要指定編碼字符集,否則將採用預設系統的字符集,很可能出現亂碼問題。StreamDecoder正是完成從位元組到字元的解碼的實現類。

FileReader繼承了InputStreamReader類,實際上是讀取檔案流,然後通過StreamDecoder解碼成char,只不過這裡的解碼字符集是預設字符集。

寫入也是類似的過程:

 

 

通過OutputStreamWriter類完成了從位元組的編碼過程,由StreamEncoder完成編碼過程。

小tip:

Ctrl+H 顯示類結構圖

Ctrl+O 檢視這個類的所有方法

Ctrl+滑鼠左鍵點選    進入這個類

 

因為這個有點長,我還沒看完I/O的工作機制所以只先發出這一段,明天再發所有,  告辭 。