開胃菜
先看一張網上流傳的
http://java.io包的類結構圖:

當你看到這幅圖的時候,我相信,你跟我一樣内心是崩潰的。
有些人不怕枯燥,不怕寂寞,硬着頭皮看源碼,但是,能堅持下去全部看完的又有幾個呢!
然而,就算源碼全部看完看懂,過不了幾天,腦子裡也會變成一團漿糊。
因為這裡的類實在太多了。可能我們反複看,反複記,也很難做到清晰明白。
他就像是一塊超級硬的骨頭,怎麼啃都啃不爛。
面對這樣的做法,要堅決對他說,NO。
記不住,怎麼辦?
我的做法是找出他們的共性,給他們分類,隻記典型,觸類旁通。
上面的圖雖然有分類,但是還不夠細,而且沒有總結出友善記憶的規律,是以我們要重新整理和歸類。
這篇文章中,使用了兩種分時給他們分組,目的是更全面的了解共性,幫助記憶。
分類一:按操作方式(類結構)
位元組流和字元流:
- 位元組流:以位元組為機關,每次次讀入或讀出是8位資料。可以讀任何類型資料。
- 字元流:以字元為機關,每次次讀入或讀出是16位資料。其隻能讀取字元類型資料。
輸出流和輸入流:
- 輸出流:從記憶體讀出到檔案。隻能進行寫操作。
- 輸入流:從檔案讀入到記憶體。隻能進行讀操作。
注意: 這裡的出和入,都是相對于系統記憶體而言的。
節點流和處理流:
- 節點流:直接與資料源相連,讀入或讀出。
- 處理流:與節點流一塊使用,在節點流的基礎上,再套接一層,套接在節點流上的就是處理流。
為什麼要有處理流?直接使用節點流,讀寫不友善,為了更快的讀寫檔案,才有了處理流。
按操作方式分類結構圖:
根據以上分類,以及jdk的說明,我們可以畫出更詳細的類結構圖,如下:
分類說明:
1) 輸入位元組流InputStream:
- ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三種基本的媒體流,它們分别從Byte 數組、StringBuffer、和本地檔案中讀取資料。
- PipedInputStream 是從與其它線程共用的管道中讀取資料。PipedInputStream的一個執行個體要和PipedOutputStream的一個執行個體共同使用,共同完成管道的讀取寫入操作。主要用于線程操作。
- DataInputStream: 将基礎資料類型讀取出來
- ObjectInputStream 和所有 FilterInputStream 的子類都是裝飾流(裝飾器模式的主角)。
2)輸出位元組流OutputStream:
- ByteArrayOutputStream、FileOutputStream: 是兩種基本的媒體流,它們分别向- Byte 數組、和本地檔案中寫入資料。
- PipedOutputStream 是向與其它線程共用的管道中寫入資料。
- DataOutputStream 将基礎資料類型寫入到檔案中
- ObjectOutputStream 和所有 FilterOutputStream 的子類都是裝飾流。
節流的輸入和輸出類結構圖:
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 極其類似,後面會有它們的對應圖。
字元流的輸入和輸出類結構圖:
分類二:按操作對象
對檔案進行操作(節點流):
- 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
該對象并不是流體系中的一員,其封裝了位元組流,同時還封裝了一個緩沖區(字元數組),通過内部的指針來操作字元數組中的資料。 該對象特點:
- 該對象隻能操作檔案,是以構造函數接收兩種類型的參數:a.字元串檔案路徑;b.File對象。
- 該對象既可以對檔案進行讀操作,也能進行寫操作,在進行對象執行個體化時可指定操作模式(r,rw)。
注意: IO中的很多内容都可以使用NIO完成,這些知識點大家知道就好,使用的話還是盡量使用NIO/AIO。
歡迎關注我的微信公衆号:"Java面試通關手冊"(一個有溫度的微信公衆号,期待與你共同進步~~~堅持原創,分享美文,分享各種Java學習資源):