Java IO,硬骨頭也能變軟

開胃菜

先看一張網上流傳的http://java.io包的類結構圖:
http://java.io包的類結構圖
當你看到這幅圖的時候,我相信,你跟我同樣心裏是崩潰的。java

有些人不怕枯燥,不怕寂寞,硬着頭皮看源碼,可是,能堅持下去所有看完的又有幾個呢!面試

然而,就算源碼所有看完看懂,過不了幾天,腦子裏也會變成一團漿糊。數組

由於這裏的類實在太多了。可能咱們反覆看,反覆記,也很難作到清晰明白。微信

他就像是一塊超級硬的骨頭,怎麼啃都啃不爛。dom

面對這樣的作法,要堅定對他說,NO。函數

記不住,怎麼辦?

個人作法是找出他們的共性,給他們分類,只記典型,舉一反三。工具

上面的圖雖然有分類,可是還不夠細,並且沒有總結出方便記憶的規律,因此咱們要從新整理和歸類。學習

這篇文章中,使用了兩種分時給他們分組,目的是更全面的瞭解共性,幫助記憶。spa

分類一:按操做方式(類結構)

字節流和字符流:線程

  • 字節流:以字節爲單位,每次次讀入或讀出是8位數據。能夠讀任何類型數據。
  • 字符流:以字符爲單位,每次次讀入或讀出是16位數據。其只能讀取字符類型數據。

輸出流和輸入流:

  • 輸出流:從內存讀出到文件。只能進行寫操做。
  • 輸入流:從文件讀入到內存。只能進行讀操做。

注意: 這裏的出和入,都是相對於系統內存而言的。

節點流和處理流:

  • 節點流:直接與數據源相連,讀入或讀出。
  • 處理流:與節點流一塊使用,在節點流的基礎上,再套接一層,套接在節點流上的就是處理流。

爲何要有處理流?直接使用節點流,讀寫不方便,爲了更快的讀寫文件,纔有了處理流。

按操做方式分類結構圖:

根據以上分類,以及jdk的說明,咱們能夠畫出更詳細的類結構圖,以下:
按操做方式分類結構圖:

分類說明:

1) 輸入字節流InputStream

  • ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三種基本的介質流,它們分別從Byte 數組、StringBuffer、和本地文件中讀取數據。
  • PipedInputStream 是從與其它線程共用的管道中讀取數據。PipedInputStream的一個實例要和PipedOutputStream的一個實例共同使用,共同完成管道的讀取寫入操做。主要用於線程操做。
  • DataInputStream: 將基礎數據類型讀取出來
  • ObjectInputStream 和全部 FilterInputStream 的子類都是裝飾流(裝飾器模式的主角)。

2)輸出字節流OutputStream:

  • ByteArrayOutputStreamFileOutputStream: 是兩種基本的介質流,它們分別向- Byte 數組、和本地文件中寫入數據。
  • PipedOutputStream 是向與其它線程共用的管道中寫入數據。
  • DataOutputStream 將基礎數據類型寫入到文件中
  • ObjectOutputStream 和全部 FilterOutputStream 的子類都是裝飾流。

節流的輸入和輸出類結構圖:

節流的輸入和輸出對照圖

3)字符輸入流Reader::

  • FileReader、CharReader、StringReader 是三種基本的介質流,它們分在本地文件、Char 數組、String中讀取數據。
  • PipedReader:是從與其它線程共用的管道中讀取數據
  • BufferedReader :加緩衝功能,避免頻繁讀寫硬盤
  • InputStreamReader: 是一個鏈接字節流和字符流的橋樑,它將字節流轉變爲字符流。

4)字符輸出流Writer:

  • StringWriter:向String 中寫入數據。
  • CharArrayWriter:實現一個可用做字符輸入流的字符緩衝區
  • PipedWriter:是向與其它線程共用的管道中寫入數據
  • BufferedWriter : 增長緩衝功能,避免頻繁讀寫硬盤。
  • PrintWriterPrintStream 將對象的格式表示打印到文本輸出流。 極其相似,功能和使用也很是類似
  • OutputStreamWriter: 是OutputStream 到Writer 轉換的橋樑,它的子類FileWriter 其實就是一個實現此功能的具體類(具體能夠研究一SourceCode)。功能和使用和OutputStream 極其相似,後面會有它們的對應圖。

字符流的輸入和輸出類結構圖:

字符流的輸入和輸出對照圖

分類二:按操做對象

按操做對象

分類說明:

對文件進行操做(節點流):

  • FileInputStream(字節輸入流),
  • FileOutputStream(字節輸出流),
  • FileReader(字符輸入流),
  • FileWriter(字符輸出流)

對管道進行操做(節點流):

  • PipedInputStream(字節輸入流),
  • PipedOutStream(字節輸出流),
  • PipedReader(字符輸入流),
  • PipedWriter(字符輸出流)。
  • PipedInputStream的一個實例要和PipedOutputStream的一個實例共同使用,共同完成管道的讀取寫入操做。主要用於線程操做。

字節/字符數組流(節點流):

  • ByteArrayInputStream,
  • ByteArrayOutputStream,
  • CharArrayReader,
  • CharArrayWriter;

除了上述三種是節點流,其餘都是處理流,須要跟節點流配合使用。

Buffered緩衝流(處理流):
帶緩衝區的處理流,緩衝區的做用的主要目的是:避免每次和硬盤打交道,提升數據訪問的效率。

  • BufferedInputStream,
  • BufferedOutputStream,
  • BufferedReader,
  • BufferedWriter,

轉化流(處理流):

  • InputStreamReader:把字節轉化成字符;
  • OutputStreamWriter:把字節轉化成字符。

基本類型數據流(處理流):用於操做基本數據類型值。

由於平時如果咱們輸出一個8個字節的long類型或4個字節的float類型,那怎麼辦呢?能夠一個字節一個字節輸出,也能夠把轉換成字符串輸出,可是這樣轉換費時間,如果直接輸出該多好啊,所以這個數據流就解決了咱們輸出數據類型的困難。數據流能夠直接輸出float類型或long類型,提升了數據讀寫的效率。

  • DataInputStream,
  • DataOutputStream。

打印流(處理流):

通常是打印到控制檯,能夠進行控制打印的地方。

  • PrintStream,
  • PrintWriter,

對象流(處理流):

把封裝的對象直接輸出,而不是一個個在轉換成字符串再輸出。

  • ObjectInputStream,對象反序列化;
  • ObjectOutputStream,對象序列化;

合併流(處理流):

  • SequenceInputStream:能夠認爲是一個工具類,將兩個或者多個輸入流當成一個輸入流依次讀取。

其餘類:File(已經被Java7的Path取代)

File類是對文件系統中文件以及文件夾進行封裝的對象,能夠經過對象的思想來操做文件和文件夾。 File類保存文件或目錄的各類元數據信息,包括文件名、文件長度、最後修改時間、是否可讀、獲取當前文件的路徑名,判斷指定文件是否存在、得到當前目錄中的文件列表,建立、刪除文件和目錄等方法。

其餘類:RandomAccessFile

該對象並非流體系中的一員,其封裝了字節流,同時還封裝了一個緩衝區(字符數組),經過內部的指針來操做字符數組中的數據。 該對象特色:

  1. 該對象只能操做文件,因此構造函數接收兩種類型的參數:a.字符串文件路徑;b.File對象。
  2. 該對象既能夠對文件進行讀操做,也能進行寫操做,在進行對象實例化時可指定操做模式(r,rw)。

注意: IO中的不少內容均可以使用NIO完成,這些知識點你們知道就好,使用的話仍是儘可能使用NIO/AIO。

歡迎關注個人微信公衆號:」Java面試通關手冊」(一個有溫度的微信公衆號,期待與你共同進步~~~堅持原創,分享美文,分享各類Java學習資源):

相關文章
相關標籤/搜索