天天看點

Java IO,硬骨頭也能變軟

開胃菜

先看一張網上流傳的

http://java.io

包的類結構圖:

Java IO,硬骨頭也能變軟

當你看到這幅圖的時候,我相信,你跟我一樣内心是崩潰的。

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

然而,就算源碼全部看完看懂,過不了幾天,腦子裡也會變成一團漿糊。

因為這裡的類實在太多了。可能我們反複看,反複記,也很難做到清晰明白。

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

面對這樣的做法,要堅決對他說,NO。

記不住,怎麼辦?

我的做法是找出他們的共性,給他們分類,隻記典型,觸類旁通。

上面的圖雖然有分類,但是還不夠細,而且沒有總結出友善記憶的規律,是以我們要重新整理和歸類。

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

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

位元組流和字元流:

  • 位元組流:以位元組為機關,每次次讀入或讀出是8位資料。可以讀任何類型資料。
  • 字元流:以字元為機關,每次次讀入或讀出是16位資料。其隻能讀取字元類型資料。

輸出流和輸入流:

  • 輸出流:從記憶體讀出到檔案。隻能進行寫操作。
  • 輸入流:從檔案讀入到記憶體。隻能進行讀操作。

注意: 這裡的出和入,都是相對于系統記憶體而言的。

節點流和處理流:

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

為什麼要有處理流?直接使用節點流,讀寫不友善,為了更快的讀寫檔案,才有了處理流。

按操作方式分類結構圖:

根據以上分類,以及jdk的說明,我們可以畫出更詳細的類結構圖,如下:

Java IO,硬骨頭也能變軟

分類說明:

1) 輸入位元組流InputStream:

  • ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三種基本的媒體流,它們分别從Byte 數組、StringBuffer、和本地檔案中讀取資料。
  • PipedInputStream 是從與其它線程共用的管道中讀取資料。PipedInputStream的一個執行個體要和PipedOutputStream的一個執行個體共同使用,共同完成管道的讀取寫入操作。主要用于線程操作。
  • DataInputStream: 将基礎資料類型讀取出來
  • ObjectInputStream 和所有 FilterInputStream 的子類都是裝飾流(裝飾器模式的主角)。

2)輸出位元組流OutputStream:

  • ByteArrayOutputStream、FileOutputStream: 是兩種基本的媒體流,它們分别向- Byte 數組、和本地檔案中寫入資料。
  • PipedOutputStream 是向與其它線程共用的管道中寫入資料。
  • DataOutputStream 将基礎資料類型寫入到檔案中
  • ObjectOutputStream 和所有 FilterOutputStream 的子類都是裝飾流。

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

Java IO,硬骨頭也能變軟

3)字元輸入流Reader::

  • FileReader、CharReader、StringReader 是三種基本的媒體流,它們分在本地檔案、Char 數組、String中讀取資料。
  • PipedReader:是從與其它線程共用的管道中讀取資料
  • BufferedReader :加緩沖功能,避免頻繁讀寫硬碟
  • InputStreamReader: 是一個連接配接位元組流和字元流的橋梁,它将位元組流轉變為字元流。

4)字元輸出流Writer:

  • StringWriter:向String 中寫入資料。
  • CharArrayWriter:實作一個可用作字元輸入流的字元緩沖區
  • PipedWriter:是向與其它線程共用的管道中寫入資料
  • BufferedWriter : 增加緩沖功能,避免頻繁讀寫硬碟。
  • PrintWriter 和PrintStream 将對象的格式表示列印到文本輸出流。 極其類似,功能和使用也非常相似
  • OutputStreamWriter: 是OutputStream 到Writer 轉換的橋梁,它的子類FileWriter 其實就是一個實作此功能的具體類(具體可以研究一SourceCode)。功能和使用和OutputStream 極其類似,後面會有它們的對應圖。

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

Java IO,硬骨頭也能變軟

分類二:按操作對象

Java IO,硬骨頭也能變軟

對檔案進行操作(節點流):

  • 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學習資源):