Java IO 流總結

Java IO 流的總結

Java IO 總結圖

IO流

我們可以看到 IO流 分爲字符流和字節流

字節流:表示字節輸入輸出流

字符流:表示字符輸入輸出流

Java中的字節流處理的最基本單位爲單個字節,它通常用來處理二進制數據。

Java中的字符流處理的最基本的單元是Unicode碼元,它通常用來處理文本數據。


下面具體說一下字符流與字節流

字節流

字節流的基類分別是 輸入流: InputStream 和輸出流: OutputStream

繼承自InputStream派生的類都含有名爲read的方法,用於讀取單個字節或字節數組。

繼承自OuputStream派生的類都含有名爲write的方法,用於寫入單個字節或字節數組。

InputStream

1, InputStream的作用

InputStream 的作用是用來表示那些從不同數據源產生輸入的類,而最終結果就是通過read方法獲得數據源的內容,從數據源中讀出的內容用int或byte[]來表示.

2, InputStream的重要方法

InputStream中的方法


  1. read() : 返回輸入流的下一個字節(next byte),如果已經到達輸入流的末尾,那麼返回-1
  2. read(byte b[]) 讀取b.length長度的字節,存入到b中,如果已經到達末尾返回-1,否則返回成功寫入到b中的字節數。
  3. read(byte b[], int off, int len) 取下len長度的字節,如果len爲0,那麼返回0,否則返回實際讀入的字節數,讀入的第一個字節存放在數據b[off]中,如果沒有可讀的,那麼返回-1。
  4. skip(long n) 跳過,並丟棄掉n個字節,其最大值爲2048。

PS: 四個方法中比較常用的 是 read(byte b[], int off, int len) 方法.

3, InputStream的具體實現類總結分析(比較常用到的)

1, ByteArrayInputStream(內存輸入流)

它接收byte[]作爲構造函數的參數,我們調用read方法時,就是從byte[]數組裏,讀取字節。

它共有兩個構造函數(主要接受 byte數組來進行讀取)

ByteArrayInputStream構造函數

2, FileInputStream(文件輸入流)

支持提供文件名、File和FileDescription作爲構造函數的參數,它的read調用的是底層的native方法。

jdk中有三個構造函數, android的sdk中該類有四個構造函數, 但是本質上都是一樣的(主要用來包裹文件)
FileInput構造函數
第一個構造函數 String 類型的 FileName(文件路徑) ,然後會把String抓換成一個File調用第二個構造函數

`public FileInputStream(String name) throws FileNotFoundException {
    this(name != null ? new File(name) : null);
}`

第三個構造函數 直接傳入一個 FileDescriptor 對象,和第二個構造函數的區別問:
如果傳入 File 則會 new 一個 FileDescriptor ,如果傳入 FileDescriptor 則會直接使用這個 對象.

3, PipedInputStream(交換輸入流)

通過通信管道來交換數據,如果兩個線程希望進行數據的傳輸,那麼它們一個創建管道輸出流,另一個創建管道輸入流,它必須要和一個PipedOutputStream相連接。

它共有四個構造函數

PipedInputStream構造函數

這四個構造函數可以分爲兩組,

`public PipedInputStream(PipedOutputStream src) throws IOException {
    this(src, DEFAULT_PIPE_SIZE);
}`

`public PipedInputStream() {
    initPipe(DEFAULT_PIPE_SIZE);
}`

這兩組的區別是 如果傳入一個 PipedOutputStream 會多一個和 PipedOutputStream 連接的方法來建立管道.

4, SequenceInputStream(合併輸入流)

將多個InputStream連接在一起,一個讀完後就完畢,並讀下一個,它接收兩個InputStream對象或者一個容納InputStream對象的容器Enumeration。

它共有兩個構造函數
SequenceInputStream構造函數

這兩個構造函數很清晰, 一個接收兩個流,一個接收多個流,它們最終會合併成一個流.

5, ObjectInputStream(對象輸入流)

和一個InputStream相關聯,源數據都是來自於這個InputStream ,主要用於對象進行反序列化, 即從一個序列化的文件中讀取數據變成對象(主要用於序列化和反序列化)

它有兩個構造函數, 其中一個 是 protected 修飾的, 就不說了,說一下 對外公佈的 構造函數

`public ObjectInputStream(InputStream in) throws IOException {
    verifySubclass();
    bin = new BlockDataInputStream(in);
    handles = new HandleTable(10);
    vlist = new ValidationList();
    enableOverride = false;
    readStreamHeader();
    bin.setBlockDataMode(true);
}`

很明顯這個構造函數是用來包裹一個 InputStream 主要用來進行反序列化的.

5, FilterInputStream

`protected FilterInputStream(InputStream in) {
    this.in = in;
}`

共1個構造函數 , 並且是 protected的類型, 不能創建對象

這個類很特殊,前面的InputStream子類都是傳入一個數據源(Pipe/byte[]/File)等等,然後通過重寫read方法從數據源中讀取數據,而FilterInputStream則是將InputStream組合在內部,它調用in去執行InputStream定義的抽象方法,也就是說它不會改變組合在內部的InputStream所對應的數據源。

另外,它還新增了一些方法,這些方法底層還是調用了read方法,但是它封裝了一些別的操作,比如DataInputStream中的readInt,它調用in連續讀取了四次,然後拼成一個int型返回給調用者,之所以採用組合,而不是繼承,目的是將(把二進制流轉換成別的格式)和(從某個數據源中讀出字節流)這兩個操作獨立開來,讓它們可以隨意地組合。

其下有三個類: BufferedInputStream(緩存流 , 常用) ; DataInputStream(不常用) ; PushbackInputStream(不常用)

  • BufferedInputStream
    有兩個構造函數

BufferedInputStream構造函數

接受一個 InputStream , 來進行緩存從而進行有效率的讀取和寫入.

6, 其他
還有一個 LineNumberInputStream extends FilterInputStream 的LineNumberInputStream 數字流

和一個 StringBufferInputStream extends InputStream 的StringBufferInputStream 字符串緩存流

這兩個流已經被棄用了,不需要考慮

InputStream 到這裏就基本完畢了, 後面是 OutPutStream ,它和InputStream是對應的篇幅較少


OuputStream

OuputStream的作用

它決定了輸出要去往的目標,和InputStream類似,也是一個抽象類,它的子類代表了輸出所要去往的目標,我們主要關注的是write方法,前兩個write方法最終都是調用了抽象的write(int oneByte)方法,最終怎麼寫入是由子類實現的。

OutputStream的具體實現類

1, ByteArrayOutputStream(兩個構造函數)

在ByteArrayOutputStream的內部,有一個可變長的byte[]數組,當我們調用write方法時,就是向這個數組中寫入數據,它還提供了toByteArray/toString方法,來獲得當前內部byte[]數組中的內容。

2, FileOutputStream(五個構造函數, 主要增加一個boolean類型的值,用來標識 是否是在文件後面添加要輸出的內容,如果爲false , 則會把文件中的數據先清空在存入, 否則直接在文件的末尾進行添加寫入)

它和 FileInputStream 類似,只不過寫入的終點換成了所打開的文件。

3, PipedOutputStream(兩個構造函數)

和PipedInputStream相關聯。用於建立 通信管道來交換數據

4, ObjectOutputStream(兩個構造函數, public 的只有一個構造函數, 傳入一個OutPutStream)

和ObjectInputStream類似,只不過它內部組合的是一個OutputStream,當調用writeObject(Object object)方法時,其實是先將Object進行反序列化轉換爲byte,再輸出到OuputStream所指向的目的地,主要用來對 object 進行序列化。

5, FilterOutputStream

它的思想和FilterInputStream類似,都是在內部組合了一個OuputStream,FilterOutputStream提供了寫入int/long/short的write重載函數,當我們調用這些函數之後,FilterOutputStream最終會通過內部的OuputStream向它所指向的目的地寫入字節。

其下有三個類: BufferedOutputStream(緩存流 , 常用) ; DataOutputStream(不常用) ; PrintStream(打印流 , 常用 ,10個構造函數, 主要用於包裹OutputStream和File)
- BufferedOutputStream,用來進行緩存進行更快速的 讀取
- PrintStream,用來更加方便的輸出

6, 注意

沒有什麼勞什子的 SequenceOutputStream(只能合併, 而不能拆分…話說怎麼拆啊 ⊙﹏⊙)

OutputStream 到這裏也基本完畢了, 後面是 字符輸入輸出流 ,內容不多


字符流: 主要用於文檔的處理

Reader字符輸入流

其實現類有

1, BufferReader

緩存流, 兩個構造類, 主要用於包裹一個 Reader , 可以使用特定的方法 readLine() 直接一行一行的讀取,這個類是 1.1加上去的, 也就是說 1.0的時候是沒有這個 Reader的緩存字符流的

`public BufferedReader(Reader in) {
    this(in, defaultCharBufferSize);
}`

`public BufferedReader(Reader in, int sz) {
    super(in);
    if (sz <= 0)
        throw new IllegalArgumentException("Buffer size <= 0");
    this.in = in;
    cb = new char[sz];
    nextChar = nChars = 0;
}`

2, InputStreamReader

轉換流, 四個構造函數, 主要用於 將流從 字節流轉換爲 字符流, 這個就是傳說中的字節流和字符流連接的橋樑O__O “…
至於爲什麼, 因爲 在Reader的所有實現類中只有它 可以接收一個 字節流 並處理, 所以它是 橋樑…

InputStreamReader構造函數

3, 其他實現類(個人感覺不常用)

1, StringReader

繼承自Reader , 只有一個構造函數 ,public StringReader(String s) ,用於讀取字符串, 功能叫少, 所以不常用

2, PipedReader

繼承自Reader , 有四個構造函數 , 通信管道來交換數據 , 主要用來包裹PipedWriter 來創建一個通道 ,不常用

3, CharArrayReader

繼承自Reader , 有兩個構造函數 , 用於讀取 字符列表

4, FilterReader

繼承自Reader , 一個構造函數(還不對外公佈) , 用於包裹一個Reader

` protected FilterReader(Reader in) {
    super(in);
    this.in = in;
}`

5, PushbackReader

繼承自FilterReader , 兩個構造函數 , 用於包裹一個Reader , 不常用

`public PushbackReader(Reader in) {
    this(in, 1);
}`

`public PushbackReader(Reader in, int size) {
    super(in);
    if (size <= 0) {
        throw new IllegalArgumentException("size <= 0");
    }
    this.buf = new char[size];
    this.pos = size;
}`

Writer字符輸出流

其實現類有

1, BufferWriter

緩存流, 兩個構造類, 用於包裹一個Writer,對應於 BufferReader

2, OutPutStreamWriter(橋樑..)

轉換流, 四個構造函數 ,繼承自Writer , 包裹OutputStream, 其他類似 InputStreamReader同時FileWriter繼承自OutputStreamWriter , 一個構造函數 , 用於包裹 Writer

3, PrintWriter

打印流 , 9個構造函數 其中:

兩個用於包裹Writer public PrintWriter(Writer out,boolean autoFlush);
兩個用於包裹OutputStream , public PrintWriter(OutputStream out, boolean autoFlush);
五個用於包裹一個File 用來進行文件輸出

4, 其他實現類(個人感覺不常用)

1, StringWriter

繼承自Writer,兩個構造函數

2, PipedWriter

繼承自Writer , 兩個構造函數

3, CharArrayWriter

繼承自Writer , 兩個構造函數

4, FilterWriter

繼承自Writer ,兩個構造函數


OVER

累了…..

繼續努力

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