1. 程式人生 > >JavaSE(一) IO類層次關系和各種IO流的用法總結

JavaSE(一) IO類層次關系和各種IO流的用法總結

思想 單位 out 9.png 什麽 輸入流 謝謝 混亂 體系

      今天把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流的用法總結