深入分析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= newFileOutputStream("");//子類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的工作機制所以只先發出這一段,明天再發所有, 告辭 。