天天看點

深入分析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操作,也就是将什麼樣的資料寫到什麼地方的問題。

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

1.1基于位元組的I/O操作接口

基于位元組的I/O操作接口輸入和輸出分别是InputStream和OutputStream

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

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

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

  

OutputStream outputStream=new FileOutputStream("");//OutputStream可以new他的子類用于實作不同的作用。      
深入分析Java I/O的工作機制 (一)

小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位元組與字元的轉化接口

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

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

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

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

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

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

寫入也是類似的過程:

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

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

小tip:

Ctrl+H 顯示類結構圖

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

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

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

轉載于:https://www.cnblogs.com/java-263/p/10264931.html