我是 啤酒就辣條,一個Java。
學而時習之,不亦說乎?但願經過博客的形式,總結、分享,梳理本身、幫助他人。
另外,啤酒就辣條,味道不錯哦~
流是一組有序的字節集合,是對數據傳輸的抽象。流的本質是數據傳輸,根據傳輸的特性,流又被分爲多種狀況。java
按照數據類型能夠分爲字符流
和字節流
。緩存
字節流
基本單位是一個字節(8bit),能夠處理全部類型的數據。app
字符流
基本代爲是多個字節(通常是兩個字節),通常處理字符數據。字符流
某種意義能夠看做,被包裝過的字節流
。由於字符流
是基於字節流
讀取以後,查了特定的碼錶,進行字符轉換的。因此,若是是字符類型的數據傳輸,首先使用字符流
,其餘傳輸使用字節流。this
按照輸入輸出方向可分爲輸入流
和輸出流
。輸入流
只能進行讀操做。輸出流
只能進行寫操做。指針
根據流的分類,可得字節輸入流,字節輸出流,字符輸入流,字符輸出流
。這四種分類分別對四個抽象類InputStream、OutputStream、Reader、Writer
,Java種全部的IO流類都是繼承其一。code
InputStream
是全部字節輸入流的超類。既然是輸入流,確定會有讀的方法read()
對象
/** * @param b 當前緩存區的數據 * @param off 當前緩存區已寫入的位置 * @param len 要讀取數據的長度 */ public int read(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int c = read(); if (c == -1) { return -1; } // 這裏能夠看出是一個bit位一個bit位讀進緩存區的 b[off] = (byte)c; int i = 1; try { for (; i < len ; i++) { c = read(); if (c == -1) { break; } b[off + i] = (byte)c; } } catch (IOException ee) { } return i; }
這個方法邏輯很清晰了,首先判斷緩存區能不能放下輸入的數據,而後以字節爲單位讀進緩存區。繼承
還有個方法是跳過或者丟棄輸入流的前n個字節,可是結果跳過的字節數可能小於n。ip
/** * @param n 要跳過的字節數 */ public long skip(long n) throws IOException { long remaining = n; int nr; if (n <= 0) { return 0; } int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining); byte[] skipBuffer = new byte[size]; while (remaining > 0) { nr = read(skipBuffer, 0, (int)Math.min(size, remaining)); if (nr < 0) { break; } remaining -= nr; } // 請注意此時 remaining 可能不爲0。 return n - remaining; }
還有幾個方法:資源
available()
返回可讀字節數的估計值。
close()
關閉字節輸入流,並釋放相應資源。
mark(int readlimit)
在輸入流種標記當前位置。
reset()
將此流從新定位到mark()的位置。
markSupported()
查詢此輸入流是否支持mark()和reset()方法。
這裏主要說明一下mark()和reset()方法。正常狀況下,一個流只能讀一次。 mark()能夠做爲標記,某一時刻使用reset()方法讓指針從新回到標記處。
OutputStream
是全部字節輸入流的超類。既然是輸入流,確定會有讀的方法write()
。
主要方法有三個。
write()
將指定的字節轉化成輸出流。
flush()
將緩存區數據強制刷新出去,刷新到文件或者外設中。
close()
關閉字節輸出流,並釋放相應資源。
對於InputStream
和OutputStream
提供的方法不少沒有帶鎖,但每每實現的時候都會帶上鎖。例如每每會加上synchronized
。
Reader
是全部字符輸入流的超類。
大部分方法和InputStream
差很少,只是從字節變成了字符。只是Reader
提供了對象級別的鎖。
protected Object lock; protected Reader() { this.lock = this; }
Writer
是全部字符輸入流的超類。固然,Writer
也提供了對象級別的鎖。
protected Object lock; protected Writer() { this.lock = this; }
除此以外,Writer
比OutputStream
多了append()
方法。
append()
方法是數據的追加。
write()
方法是數據的覆蓋。