java I/O總結

IO是非常重要的一塊,但通常又被人們所忽視,這裏希望能有個很清晰的介紹。自己學習的同時希望能夠給別人帶來一些幫助,對文章中用到其他作者(已經給出了鏈接)的圖片在這裏表示感謝!

IO的分類

java IO可以分成兩類:
(1)基於字節操作的io接口:InputStream 和 OutputStream
(2)基於字符操作的io接口:Writer 和 Reader
不論是磁盤還是網絡傳輸,他們的最小單位都是字節,但是程序中的數據大多都是以字符的形式呈現,所以java也提供了對字符流的支持。還有一點需要注意的是,數據的傳輸方式也很重要,即數據寫到哪裏的問題,一般是一下兩種方式:
1. 基於磁盤操作的io接口:File
2. 基於網絡操作的io接口:Socket

IO流的整體結構

這裏寫圖片描述
圖片引用自( 引用塊內容

InputStream的類層次結構

這裏寫圖片描述

OutputStream的類層次結構

這裏寫圖片描述

以上圖片引用自(這裏寫鏈接內容

Reader和Writer類的層次關係

Reader是java IO中所有的Reader的基類。類似於InpuStream,不同點在於Reader是基於字符的,也就是Reader用於讀取文本,而InpuStream用於讀取原始的字節。

java中使用UTF8編碼來表示字符串,這在字節流和字符流進行轉換的時候需要注意。如果從輸入流中一字節爲單位讀取UTF8編碼的文本,並且嘗試將讀到的字節轉換成字符,這個時候可能會出錯!

Writer是java IO中的所有Writer的基類,同樣Writer是基於字符而不是字節,用於寫入文本。

這裏寫圖片描述
圖片引用自(這裏寫鏈接內容)

字節流和字符流的轉換

數據的持久化和網絡傳輸都是以字節的形式進行的,所以字節流和字符流之間必然存在轉換的問題。轉換分爲兩個方向:字節到字符的轉換和字符到字節的轉換。這裏主要涉及到編碼和解碼的問題,舉例來說,InputStream.read()方法在數據流中讀取字節(read()每次都只讀取一個字節,效率非常慢,我們一般都是使用read(byte[])),然後保存在一個byte[]數組中,最後轉換爲String。在我們讀取文件時,讀取字節的編碼取決於文件所使用的編碼格式,而在轉換爲String過程中也會涉及到編碼的問題,如果兩者之間的編碼格式不同可能會出現問題。例如存在一個*.txt編碼格式爲UTF-8,那麼通過字節流讀取文件時所獲得的數據流編碼格式就是UTF-8,而我們在轉化成String過程中如果不指定編碼格式,則默認使用系統編碼格式(GBK)來解碼操作,由於兩者編碼格式不一致,那麼在構造String過程肯定會產生亂碼。

字節轉換成字符的橋樑是InputStreamReader,他使用指定的charset讀取字節並將其解碼爲字符。我們既可以指定編碼方式也可以接受平臺的默認字符集。

基類InputStream和其實現類

圖片引用自(這裏寫鏈接內容)
這裏寫圖片描述

構造方法:
InputStream() 創建一個輸入的stream流
其他方法
1. close():關閉stream方法,這個是每次在用完流之後必須調用的方法。
2. read():方法是讀取一個byte字節,但是返回的是int。
3. read(byte[]):一次性讀取內容到緩衝字節數組
4. read(byte[],int,int):從數據流中的哪個位置offset開始讀長度爲len的內容到緩衝字節數組
5. skip(long):從stream中跳過long類型參數個位置

InputStream的實現類

@ByteArrayInputStream– 把內存中的一個緩衝區作爲 InputStream 使用 .

構造方法
(A)ByteArrayInputStream(byte[]) 創建一個新字節數組輸入流( ByteArrayInputStream ),它從指定字節數組中讀取數據(使用byte作爲緩衝區數組)
(B)ByteArrayInputStream(byte[], int, int) 創建一個新字節數組輸入流,它從指定字節數組中讀取數據。
舉例:
byte[] buff = new byte[] { 2, 15, 67, -1, -9, 9 };
ByteArrayInputStream in = new ByteArrayInputStream(buff, 1, 4);

@StringBufferInputStream – 把一個 String 對象作爲 InputStream .

構造方法
StringBufferInputStream(String) 據指定串創建一個讀取數據的輸入流串。

@ FileInputStream – 把一個文件作爲 InputStream ,實現對文件的讀取操作

構造方法
(A)FileInputStream(File name) 創建一個輸入文件流,從指定的 File 對象讀取數據。
(B)FileInputStream(FileDescriptor) 創建一個輸入文件流,從指定的文件描述器讀取數據。
(C)-FileInputStream(String name) 創建一個輸入文件流,從指定名稱的文件讀取數據。

@PipedInputStream :實現了 pipe 的概念,主要在線程中使用 . 管道輸入流是指一個通訊管道的接收端。

構造方法
(A)PipedInputStream() 創建一個管道輸入流,它還未與一個管道輸出流連接。
(B)PipedInputStream(PipedOutputStream) 創建一個管道輸入流 , 它已連接到一個管道輸出流。

@ SequenceInputStream :把多個 InputStream 合併爲一個 InputStream . “序列輸入流”類允許應用程序把幾個輸入流連續地合併起來並且使它們像單個輸入流一樣出現。每個輸入流依次被讀取,直到到達該流的末尾。然後“序列輸入流”類關閉這個流並自動地切換到下一個輸入流。

構造方法
SequenceInputStream(Enumeration) 創建一個新的序列輸入流,並用指定的輸入流的枚舉值初始化它。
SequenceInputStream(InputStream, InputStream) 創建一個新的序列輸入流,初始化爲首先 讀輸入流 s1, 然後讀輸入流 s2 。

@ObjectInputStream:用於操作Object的stream,這個在stream主要用在對象傳輸的過程中,其中牽涉到了序列化的知識

構造方法
ObjectInputStream():實例化一個ObjectInputStream對象
ObjectInputStream(InputStream):使用一個InputStream對象來實例化一個ObjectInputStream對象,其中InputStream就是對象的輸入流

@ FilterInputStream:是一個過濾的InputStream

構造方法
FilterInputStream(InputStream):使用一個InputStream爲參數實例化一個FilterInputStream,這是一個裝飾者模式,從他子類的構造方法就可以看出端倪。他擁有子類如下:

1)BufferedInputStream:使用緩衝區的stream
構造方法
BufferedInputStream(InputStream):使用InputStream爲參數初始化實例
BufferedInputStream(InputStream,int):能夠設置緩衝區大小的BufferedInputStream

2)DataInputStream:數字格式化的stream
構造方法
DataInputStream(InputStream):使用InputStream參數來初始化實例

基類OutputStream

OutputStream
構造方法
OutputStream()
其他方法
1. write(int):寫入一個字節到stream中
2. write(byte[])寫入一個byte數組到stream中
3. write(byte[],int,int):把byte數組中從offset開始處寫入長度爲len的數據
4. close():關閉流,這個是在操作完stream之後必須要調用的方法
5. flush():這個方法是用來刷新stream中的數據,讓緩衝區中的數據強制的輸出
繼承的子類如下:

@ByteArrayOutputStream : 把信息存入內存中的一個緩衝區中 . 該類實現一個以字節數組形式寫入數據的輸出流。

構造方法
(A)— ByteArrayOutputStream() 創建一個新的字節數組輸出流。
(B)— ByteArrayOutputStream() 創建一個新的字節數組輸出流。
(C)— ByteArrayOutputStream(int) 創建一個新的字節數組輸出流,並帶有指定大小字節的緩衝區容量。

@ FileOutputStream: 文件輸出流是向 File 或 FileDescriptor 輸出數據的一個輸出流

構造方法
(A)FileOutputStream(File name) 創建一個文件輸出流,向指定的 File 對象輸出數據。
(B)FileOutputStream(FileDescriptor) 創建一個文件輸出流,向指定的文件描述器輸出數據。
(C)FileOutputStream(String name) 創建一個文件輸出流,向指定名稱的文件輸出數據。
(D)FileOutputStream(String, boolean) 用指定系統的文件名,創建一個輸出文件。

@ PipedOutputStream: 管道輸出流是指一個通訊管道的發送端。 一個線程通過管道輸出流發送數據,
而另一個線程通過管道輸入流讀取數據,這樣可實現兩個線程間的通訊。

構造方法
(A)PipedOutputStream() 創建一個管道輸出流,它還未與一個管道輸入流連接。
(B)PipedOutputStream(PipedInputStream) 創建一個管道輸出流,它已連接到一個管道輸入流。

@ObjectOutputStream:輸出Object對象的stream

構造方法
ObjectOutputStream:實例化一個ObjectOutputStream對象
ObjectOutputStream(OutputStream):使用OutputStream對象來實例化一個ObjectOutputStream對象,將對象寫入到OutputStream中

@FilterOutputStream:過濾的OutputStream,下面幾個是他的子類

構造方法
FilterOutputStream(OutputStream):使用OutputStream參數實例化FilterOutputStream

@BufferedOutputStream:帶有緩衝區的stream

構造方法
BufferedOutputStream(OutputStream):使用OutputStream參數初始化BufferedOutputStream類
BufferedOutputStream(OutputStream,int):在初始化實例的時候指定緩衝區的大小

@ DataOutputStream:具有格式化的OutputStream

構造方法
DataOutputStream(OutputStream):使用OutputStream參數來初始化DataOutputStream實例

@PrintStream:直接輸出到控制檯中:我們最熟悉的就是System.out他就是一個PrintStream

構造方法
PrintStream(OutputStream):使用OutputStream參數來實例化PrintStream

字符流Stream——Reader和Writer

Reader基類:基於字符流的stream
構造函數
Reader():無參的構造方法

@CharArrayReader :與 ByteArrayInputStream 對應此類實現一個可用作字符輸入流的字符緩衝區
構造函數
CharArrayReader(char[]) 用指定字符數組創建一個 CharArrayReader 。
CharArrayReader(char[], int, int) 用指定字符數組創建一個 CharArrayReader

@ StringReader : 與 StringBufferInputStream 對應其源爲一個字符串的字符流。

@ FileReader : 與 FileInputStream 對應

@ PipedReader :與 PipedInputStream 對應

@ InputStreamReader:將InputStream轉化成Reader

基類Writer

@CharArrayWriter: 與 ByteArrayOutputStream 對應

@ StringWriter:無與之對應的以字節爲導向的 stream

@ FileWriter: 與 FileOutputStream 對應

@ PipedWriter:與 PipedOutputStream 對應

@ OutputStreamWriter:將OutputStream轉化成Writer

@ PrintReader:和PrintStream對應

字節流和字符流Stream 之間的轉換
@ InputStreamReader 和 OutputStreamReader :
把一個以字節爲導向的 stream 轉換成一個以字符爲導向的 stream 。
InputStreamReader 類是從字節流到字符流的橋樑:它讀入字節,並根據指定的編碼方式,將之轉換爲字符流。
使用的編碼方式可能由名稱指定,或平臺可接受的缺省編碼方式。
InputStreamReader 的 read() 方法之一的每次調用,可能促使從基本字節輸入流中讀取一個或多個字節。
爲了達到更高效率,考慮用 BufferedReader 封裝 InputStreamReader ,
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章