天天看點

Java_io體系之概念與整體結構——02Java_io體系之概念與整體結構——02

Java_io體系之概念與整體結構——02

一:寫給自己、可無視

       剛從校門走出來時、覺得先上手工作、現在基本能打打醬油的、沒有一開始進入社會的那種彷徨了、回頭想想自己的程式猿之路。接觸java加上填鴨式的三個月教育訓練也就半年出頭。很短、整天想着學些時髦的東西、架構、JSON、資料庫、作業系統、實際的部署、項目的管理、、、看着大神飛速的代碼式原理講解、一臉的豔羨看着大神使用着各種新東西、各種工具、視窗上飛速敲出來的各種指令的、浏覽的各種自己覺得太遠的網站、自己寫的項目、、、覺得自己真一土鼈、學!今天學點這個、明天學點那個、忙的像個陀螺、靜下心來做個總結、看着光标閃半天、不知道自己能寫什麼、好不容易寫出點東西、過短時間回頭一看、這是什麼?多次無奈之下請教大神、大神說先抛開這些、問你幾個問題:你覺得你java基礎學的怎麼樣?我腦中立馬浮現的教育訓練的各種内容、有印象、但是講?不知道講啥、、你了解的類之間的關系有哪些?腦中立馬蹦出繼承?引用?、、你知不知道一個request的請求過程?知不知道tomcat的工作原理?啞口無言、、大神沒有說什麼答案、隻是說先把基礎東西了解了再說吧。

想想就從IO開始、在學習流的時候、就是先例子、學到一個、當時會用一個流的write、read、内部是怎麼實作的?不知道、也沒有想過去看看、知道io有很強的對稱性、位元組流、字元流、具體的内部差別也是一臉茫然、不同的位元組流之間有什麼差別、為什麼會有這樣的差別?經常看到好多流都有同樣的方法、但是作用卻不同、為什麼?不知道、、隻是知道有差別、使用的時候也就是用一兩個熟悉的、還不知道對不對、遇到問題就上網查、查到就copy下來、打完收工、、、、為什麼?這不是實作了麼、還要為什麼幹嘛、突然想起來要是某天有人叫你講講io、張嘴不知道講什麼、很多類不用的基本都忘的差不多了、知道的也隻是僅限于api。

 浮躁的社會、浮躁的心。學的東西是很多、學不完、但是想走的遠、覺得還是先吧基礎的掌握了吧、還有就是覺得學東西要有目标、東拼西湊的最終結果就是那些最後還是别人的、自己就像一個漏鬥。。。廢了半天的話隻是想留個印記、以後看的時候能知道自己此刻在想些什麼。

僅是個人的總結、總有不足之處、望見諒與指正、不勝感激!

二:流的概念與分類:

1.   概念:

關于流的概念版本很多、主要還是了解、下面僅個人了解。

流(Stream)、輸入或者輸出管道中一串連續不斷的有序資料、我們可以用以下情況做聯想、有一個水管、水管從水的源頭不斷的将水抽取到管道中形成一股水流、這種情況下、水管中連續不斷的水就是流、相當于IO中輸入流管道(水管)從資料源頭中讀取到輸入流管道中的一串有序資料。同樣、輸出流管道盛放的水也是流、輸出流管道可以将水輸送到另一個水桶或者别的盛放水的地方、可以把輸入流管道的指向稱作源(提供流的地方)、吧輸出流管道的指向稱作目的地(接收流的地方)。流隻存在于管道中。

       上面管道中的水就是一串有序資料、也就是流!

而我們平常說的輸入輸出流、其實是輸入流管道、輸出流管道、與輸入流管道相連的盛放資料的媒介就是流的源頭、用于提供輸入流管道吸取的流。與輸出流管道相連的就是流的目的地、就是接收輸出流管道中流的媒介。這些媒介可以是記憶體、磁盤、網絡等。

2.分類:

a. 從流的方向上分為兩類:

1、         輸入流:從資料源中将資料讀取到程式中的流。

2、         輸出流:程式将資料寫入到目的地的流。

注:輸入輸出是從某個角度出發去區分的、java中是站在程式的角度來區分流的輸入輸出的。将資料讀取到程式中的就是輸入流、将程式中的資料寫出去的就是輸出流。

b. 從流的資料類型上分為兩類:

1、         位元組流:以8位的位元組形式來讀寫的流。他們的标志是名稱以Stream結尾。InputStream、OutputStream分别是所有位元組輸入流、位元組輸出流的父類。

2、         字元流:以字元形式來讀寫的流。他們的标志是名稱以Writer或者Reader結尾。并且Writer、Reader分别是所有字元輸出流、字元輸入流的父類。

c. 從流的角色可以分成兩類:

1、         節點流:從/向一個特定的IO裝置(如網絡、磁盤)讀/寫資料的流。也被稱為低級流(Low Level Stream)。

2、         處理流:對一個已經存在的流進行連接配接或者封裝、通過封裝後的流來進行讀/寫、也被稱為進階流。

三:IO體系結構圖

       前面有個引用的IO的設計模式介紹、如果對他有點了解的話對了解IO還是很有幫助的、通過對java類庫的學習也可以體會他在設計用到的設計思想、不但能加深了解、還可以提高自己的設計方面修為。這些都是潛移默化的東西、慢慢積累、、

       下面按位元組流輸入流(InputStream)、位元組輸出流(OutputStream)、字元輸入流(Reader)、字元輸出流(Writer)、以及他們之間的對應關系這幾個子產品來介紹IO整體結構、當然也沒有介紹全部的IO類、很少使用的暫不說(下面的圖借用了skywang12345的部落格IO體系圖、歸納的很好、沒有再重複去畫)。對圖中的類進行簡單說明、後面會有源碼和測試。

1.   InputStream:位元組輸入流

Java_io體系之概念與整體結構——02Java_io體系之概念與整體結構——02

1、         InputStream :位元組輸入流、是所有位元組輸入流的父類、為所有位元組輸入流提供一個标準、和基本的與讀取位元組有關的方法及簡單的實作。

2、         ByteArrayInputStream :位元組數組輸入流、用于讀取其内置緩存位元組數組中的位元組。記憶體緩存位元組數組中資料的來源是在建構ByteArrayInputStream時傳入的位元組數組。

3、         PipedInputStream :管道位元組輸入流、必須與PipedOutputStream(管道位元組輸出流)結合使用、用于線程之間的通信。

4、         FilterInputStream :過濾器位元組輸入流、僅僅是重寫InputStream方法、為位元組輸入處理流提供标準。

5、         BufferedInputStream :緩沖位元組輸入流、裝飾類、用于裝飾節點類型的位元組輸入流、為其提供緩沖功能、減少通路次數、提高效率。

6、         DataInputStream :資料位元組輸入流、裝飾類、裝飾位元組節點輸入流、一般與DataOutputStream結合使用、用于讀取DataOutputStream寫入到目的地中的java基礎類型的資料。

7、         FileInputStream :檔案位元組輸入流、以位元組的形式将檔案中資料讀取到程式中、進行下一步操作。

a)      File、既可以表示檔案夾、也可以表示具體的檔案。這裡需要是具體的檔案。

b)     檔案描述符、可以被用來表示開放檔案、開放套接字等。可以通過它來建立對其描述的檔案進行讀寫的流

8、ObjectInputStream :對象位元組輸入流、與ObjectOutputStream結合使用、用于将使用ObjectOutputStream寫入目的地的java對象(一般是javabean)讀取到程式中、進行下一步操作。

2.   OutputStream:位元組輸出流

Java_io體系之概念與整體結構——02Java_io體系之概念與整體結構——02

1、         OutputStream:位元組輸出流、本身是一個抽象類、與InputStream作用一樣、為所有位元組輸出流提供一個标準、定義了一些基本寫入位元組的方法與簡單實作。

2、         ByteArrayOutputStream:位元組數組輸出流、用于将位元組寫入到其本身所帶的一個内置緩存位元組數組中、可将其内置緩存位元組數組中的位元組轉化成字元串到程式中、也可以将它寫入到另一個位元組輸出流中。

3、         PipedoutputStream : 管道位元組輸出流、在上邊介紹過了、必須與PipedInputStream結合使用、用于線程之間的通信。

4、         FilterOutputStream :過濾位元組輸出流、僅僅重寫了父類OutputStream的方法、是位元組輸出處理流的父類。

5、         BufferedOutputStream : 緩沖位元組輸出流、裝飾類、為低級位元組輸出流添加緩沖功能、提高效率、減少通路次數。

6、         DataOutputStream : 資料位元組輸出流、裝飾類。用于裝飾節點輸出流、功能是将java基礎類型以一種與系統無關的方式寫入到目的地中、可用DataInputStream讀取。

7、         PrintStream :位元組列印流、裝飾類、這是一個功能很強的流、對低級位元組輸出流進行裝飾、提供列印各種資料類型的功能、列印的目的地不僅僅是控制台、可以是檔案、記憶體、網絡等、同時還可以指定自動flush功能。

8、         FileOutputStream :檔案位元組輸出流、将位元組寫入指定的檔案中。這裡牽扯到的File可以看上面FileInputStream中對他們的簡單說明。

9、         ObjectOutputStream :對象位元組輸出流、用于将java的對象(一般是javabean)寫入輸出流管道中、存儲到某媒體中、可使用ObjectInputStream讀取被其寫入的對象。

3.   InputStream與OutputStream之間的對應關系

Java_io體系之概念與整體結構——02Java_io體系之概念與整體結構——02

InputStream與OutputStream及其子類之間有很強的對稱性。下圖很形象的展現出來他們之間的對應關系。隻有PrintStream沒有對應的。

字元流的出現、隻是讓IO體系顯得有國際範、不過在某些時候也确實友善了一些、說到實用還是位元組流、因為絕大多數資料都是以位元組的形式存儲在各種存儲媒體中的。

4.   Reader :字元輸入流

Java_io體系之概念與整體結構——02Java_io體系之概念與整體結構——02

1、         Reader、意義與InputStream相同、為所有字元輸入流提供一個标準、隻有基本的讀取方法的定義和簡單的實作。

2、         CharArrayReader :字元數組輸入流、将其内置字元緩存數組中的資料(通過構造方法傳入)讀取到程式中。内置字元緩存數組中資料的來源是在構造CharArrayReader時傳入的字元數組。

3、         PipedReader :管道字元輸入流:必須與PipedWriter結合使用、用于線程之間的通信。

4、         FilterReader : 字元過濾流、僅僅簡單的重寫了Reader中的包含的方法、并且沒有具體的直接的子類。個人覺得其意義在于留下一個擴充的點。如同FilterInputStream。

5、         BufferedReader :緩沖字元輸入流。裝飾類、為低級字元輸入流提供緩沖功能、提高效率。并且這裡不再繼承FilterReader、而是直接繼承Reader。

6、         InputStreamReader :位元組轉換流、将位元組流轉換成字元流、不僅僅可以将低級位元組流輸入流轉換成字元輸入流、還可以将進階位元組輸入流轉換成字元輸入流、可以指定位元組轉成字元時使用的編碼、所有具有指定編碼或者編碼集的字元輸入流内部都是調用了此流來轉換底層流。

7、         FileReader :檔案字元輸入流、以字元的形式讀取檔案中的内容。當檔案内容是位元組時則可能會有問題、對其牽扯到的File不再唠叨。

5.   Writer :字元輸出流

Java_io體系之概念與整體結構——02Java_io體系之概念與整體結構——02

1、         Writer :字元輸出流、是所有字元輸出流的父類。與OutputStream意義一樣、提供一個标準、一些基本寫入的方法和簡單的實作。

2、         CharArrayWriter : 字元輸出流、用于将字元寫入其内置緩存字元數組中。可以将寫入的字元緩存數組轉換成字元串或者寫入其他字元輸出流中。

3、         PipedWriter : 管道字元輸出流、必須與PipedReader結合使用、用于線程之間的通信。

4、         BufferedWriter : 緩存字元輸出流、用于裝飾低級字元輸出流、為其提供緩沖功能、提高效率。

5、         OutputStreamWriter :位元組輸出流轉換成字元輸出流、用于将位元組輸出流轉化成字元輸出流。可以使用指定編碼轉化。為提高效率、通常使用BufferedWriter對其包裝。

6、         FileWriter :檔案字元輸出流、繼承OutputStreamWriter、用于将字元寫入到指定檔案中。File也不再唠叨。

7、         PrintWriter :字元列印流、同樣很強大、可以将各種資料以字元的形式列印到指定目的地中、本身也是個裝飾流。但是flush與PrintStream有差別。

6.   Reader與Writer之間的對應關系

Java_io體系之概念與整體結構——02Java_io體系之概念與整體結構——02

同樣:Reader與Writer之間的對應關系也很明确。隻有PrintWriter沒有對應的輸入流。且因為其直接操作的對象是字元、是以沒有那麼多複雜的裝飾和繼承關系。結構更加明确。

7.   位元組向字元轉換的編碼過程

Java_io體系之概念與整體結構——02Java_io體系之概念與整體結構——02

8.   位元組向字元轉換的解碼過程

Java_io體系之概念與整體結構——02Java_io體系之概念與整體結構——02

這裡要注意的是: javaIO中隻有将位元組流轉換成字元流的方法、沒有字元流轉換成位元組流的方法。原因很簡單、沒有必要。

9.   輸入位元組流、輸入字元流之間對應關系

Java_io體系之概念與整體結構——02Java_io體系之概念與整體結構——02

10. 輸出位元組流、輸出字元流之間對應關系:

Java_io體系之概念與整體結構——02Java_io體系之概念與整體結構——02

四:總結

       流的了解還是有點饒人的、要弄清IO、首先就要弄清他的整體體系、不僅僅是輸入輸出、位元組、字元、還要清楚他們之間的繼承關系、使用的差別、多方面進行對比、多動手試試差異。

位元組與字元流之間的本質差別:僅僅是操作的單元不一樣!有些資料既可以使用位元組流、又可以使用字元流、因為這些資料既可以用字元表示也可以用位元組表示。比如上面絕大多數的流、有些隻能用位元組流、比如ByteArrayInputStream、ByteOutputStream、DataInputStream、DataOutputStream、ObjectInputStream、ObjectOutputStream、因為他的操作對象隻能是位元組、并且不能将這些位元組轉換成字元。