JavaSE(一) IO類層次關系和各種IO流的用法總結
今天把IO流的這一知點進行一下總結,因為在之前使用io流的時候,就只知道幾個重點常用的IO類,比如FileInputStream,BufferedInputStream(緩沖流)等等,但是不知道它處於整個IO體系中的什麽位置,對於其中的整個IO體系一點不了解,每次使用的時候都需要百度查看用法例子,這就說明自己對這塊的知識有所欠缺,所以今天,來詳細的分析,解剖一下IO的整個結構。
借鑒博文:http://www.cnblogs.com/skywang12345/p/io_01.html 該博主寫的非常好,自己重新寫一遍是因為想按照自己的思路進行總結,方便日後自己復習。有雷同是肯定的。謝謝
--WH
一、IO流的分類
1.1、按數據流的方向分為 輸入流、輸出流
此輸入、輸出是相對於我們寫的代碼程序而言,
輸入流:從別的地方(本地文件,網絡上的資源等)獲取資源 輸入到 我們的程序中
輸出流:從我們的程序中 輸出到 別的地方(本地文件), 將一個字符串保存到本地文件中,就需要使用輸出流。
1.2、按處理數據單位不同分為 字節流、字符流
1字符 = 2字節 、 1字節(byte) = 8位(bit) 、 一個漢字占兩個字節長度
字節流:每次讀取(寫出)一個字節,當傳輸的資源文件有中文時,就會出現亂碼,
字符流:每次讀取(寫出)兩個字節,有中文時,使用該流就可以正確傳輸顯示中文。
1.3、按功能不同分為 節點流、處理流
節點流:以從或向一個特定的地方(節點)讀寫數據。如FileInputStream
處理流:是對一個已存在的流的連接和封裝,通過所封裝的流的功能調用實現數據讀寫。如BufferedReader。處理流的構造方法總是要帶一個其他的流對象做參數。一個流對象經過其他流的多次包裝,
這裏就涉及到了裝飾者模式,在後面會詳細講解該模式在IO中的體現。
1.4、4個基本的抽象流類型,所有的流都繼承這四個。
輸入流 輸出流
字節流 InputStream outputStream
字符流 Reader Writer
inputStream:字節輸入流
outputStream:字節輸出流
Reader:字符輸入流
Writer:字符輸出流
1.5、總結流的分類
看上面的幾個分類,可能對於初次學io的同學會感覺到有些混亂,那什麽時候用字節流,什麽時候該用輸出流呢?其實非常簡單,舉一個例子就學會了,
1、首先自己要知道是選擇輸入流還是輸出流,這就要根據自己的情況而定,如果你想從程序寫東西到別的地方,那麽就選擇輸出流,反之用輸入流
2、然後考慮你傳輸數據時,是選擇使用字節流傳輸還是字符流,也就是每次傳1個字節還是2個字節,有中文肯定就選擇字符流了。
3、前面兩步就可以選出一個合適的節點流了,比如字節輸入流inputStream,如果要在此基礎上增強功能,那麽就在處理流中選擇一個合適的即可。
二、4個基本抽象類的繼承關系分析
2.1、InputStream 字節輸入流
2.1.1、認識每個類的功能即作用
現在就認識一下即可,詳細的功能會在後面的博客中寫出來。
ByteArrayInputStream:字節數組輸入流,該類的功能就是從字節數組(byte[])中進行以字節為單位的讀取,也就是將資源文件都以字節的形式存入到該類中的字節數組中去,我們拿也是從這個字節數組中拿
PipedInputStream:管道字節輸入流,它和PipedOutputStream一起使用,能實現多線程間的管道通信
FilterInputStream :裝飾者模式中處於裝飾者,具體的裝飾者都要繼承它,所以在該類的子類下都是用來裝飾別的流的,也就是處理類。具體裝飾者模式在下面會講解到,到時就明白了
BufferedInputStream:緩沖流,對處理流進行裝飾,增強,內部會有一個緩存區,用來存放字節,每次都是將緩存區存滿然後發送,而不是一個字節或兩個字節這樣發送。效率更高
DataInputStream:數據輸入流,它是用來裝飾其它輸入流,它“允許應用程序以與機器無關方式從底層輸入流中讀取基本 Java 數據類型”
FileInputSream:文件輸入流。它通常用於對文件進行讀取操作
File:對指定目錄的文件進行操作,具體可以查看講解File的博文。註意,該類雖然是在IO包下,但是並不繼承自四大基礎類。
ObjectInputStream:對象輸入流,用來提供對“基本數據或對象”的持久存儲。通俗點講,也就是能直接傳輸對象,
2.2、OutputStream 字節輸出流
具體分析在上面分析過了,只不過和inputStream是相對的,但作用是相同的。
2.3、Reader 字符輸入流
功能也差不多,類似。這裏分析一個。
InputStreamReader:轉換流 將 字節輸入流 轉換為 字符輸入流。它是字節流通向字符流的橋梁
2.4、Writer 字符輸出流
三、裝飾者模式的運用
3.1、什麽是裝飾者模式?
推薦一篇博文,http://blog.csdn.net/jason0539/article/details/22713711 就詳細說明了什麽是裝飾者模式?用我自己的話來說,就是往一個添加更多的功能,而我們首先想到的是繼承,繼承就很好的符合了我們的要求,不管你想加多少層的功能,都可以使用繼承一層層的實現,但是這帶來了一個問題,一旦我需要改變我的需求,那麽我就需要往源碼中改東西,再就是在這個繼承鏈中某個類做一些修改,這不符合我們的設計模式思想,所以就有了裝飾者模式,裝飾者中擁有被裝飾者的實例,然後有什麽具體的裝飾我們都另寫一個類來繼承該裝飾者,當我們需要該裝飾時,就new出該類來,然後將其被裝飾者當作參數傳遞進去。
關說可能沒理解那麽清楚,現在來看看一個具體的實例。比如,我們需要制作一份雞腿堡,流程是怎樣的呢?看下圖
1、先有基本原料,也就是兩塊面包,這是不管做什麽漢堡都需要的,
2、做什麽漢堡,取決於加什麽材料,比如生菜,雞肉等,所以根據材料來做漢堡,想做什麽漢堡就加什麽材料
3、所有材料加完之後,直接計算價格即可
這樣使用裝飾者模式,是不是比一直使用繼承方便的多的多呢?換一種漢堡,也不需要改源碼,什麽也不需要,希望你能夠理解清楚其中的思想。
3.2、io流中的裝飾者模式的運用
畫張圖,在結合源碼和自己寫的代碼來看。
到這裏,應該可以對前面的處理流和節點流有所理解了把,其實處理流就是一個具體的裝飾者,而節點流就是被裝飾者。
四、總結
4.1、應該知道io流的各種類的結構關系,平常我們使用的io類是處於什麽樣的位置,是一個什麽樣的流(節點流還是處理流,輸入流還是輸出流,字節流還是字符流)
4.2、裝飾者模式在io流中的運用和什麽是裝飾者模式
4.3、為什麽在使用io流時會將是那樣的格式進行編寫,將一個流的實例放入另一個流的構造方法中?
JavaSE(一) IO類層次關系和各種IO流的用法總結