[五] JavaIO之InputStream OutputStream簡介 方法列表說明
InputStream 和 OutputStream 對於位元組流的輸入和輸出
是作為協議的存在
所以有必要了解下這兩個類提供出來的基本約定
這兩個類是抽象類,而且基本上沒什麼實現,都是依賴於子類具體的去實現
但是他是對於其子類 協議綱領一般的存在
瞭解清楚每一個方法含義,對於後續具體的子類將會有非常大的幫助
基本含義
InputStream | 所有位元組輸入流的 超類 他是一個抽象類 |
OutputStream | 所有位元組輸出流的 超類 他是一個抽象類 |
方法列表
InputStream 包含了讀取方法以及輔助方法
OutputStream包含了寫入方法以及輔助方法
方法對照
read() read(byte[]) read(byte[], int, int) |
write(byte[]) write(byte[], int, int) write(int) |
close | close |
flush() | |
available() mark(int) markSupported() reset() skip(long) |
方法詳解
read
read() 從輸入流中讀取資料的下一個位元組。返回 0 到 255 範圍內的 int 位元組值 如果因為已經到達流末尾而沒有可用的位元組,則返回值 -1 |
方法將會一直阻塞,直到資料可用,檢測到流的末尾或者丟擲異常 |
無引數的read() 是抽象方法,由實現類提供實現 三個read方法實際上根本方法都是read()方法 其他兩個方法為拓展功能,邏輯便捷方法 |
無引數的read()返回的資料為讀取到的位元組值 而有引數的則是讀取到位元組陣列中,所以返回值為讀取到的個數 |
read方法關鍵點 要麼就是直接返回讀取的位元組 要麼就是將讀取到的位元組放入位元組陣列中,位元組陣列是你傳遞進去的 |
write
write(int b) 將指定的位元組寫入此輸出流 write 的常規協定是:向輸出流寫入一個位元組, 要寫入的位元組是引數 b 的八個低位 b 的 24 個高位將被忽略 說白了就是寫入的是byte雖然引數是int |
write(byte[] b) 將 b.length 個位元組從指定的 byte 陣列寫入此輸出流 write(b) 的常規協定是:應該與呼叫 write(b, 0, b.length) 的效果完全相同 |
write(byte[] b,int off,int len) 將指定 byte 陣列中從偏移量 off 開始的 len 個位元組寫入此輸出流 write(b, off, len) 的常規協定是:將陣列 b 中的某些位元組按順序寫入輸出流; 元素 b[off] 是此操作寫入的第一個位元組,b[off+len-1] 是此操作寫入的最後一個位元組 |
類似read的呼叫形式 直接寫入指定位元組的write(int b) 方法是根本 其他的是拓展功能 |
read() 與write(int b) 是根本的讀取一個位元組或者寫入一個位元組的方法
其餘形式是針對傳入位元組陣列作為引數,以及指定位元組陣列的偏移量時的一些拓展功能
一旦傳遞了位元組陣列作為引數
read將會讀取資料到位元組陣列
write將會將位元組陣列的資料寫入
close
都需要關閉流,所以都有close方法 都是關閉流並釋放與此流有關的系統資源 都可能丟擲IOException |
在InputStream和OutputStream中,兩個close方法都是空方法 |
flush
flush的含義為重新整理,在寫入資料時使用 所以,只有輸出流擁有flush方法 |
之所以需要重新整理,是因為有的輸出流的寫方法實現,可能已經緩衝了以前寫入的任何位元組 那麼,這個方法用於提供能夠立即將資料寫入到磁碟的功能 不過,只是立即請求作業系統進行處理,而不保證這些位元組實際已經寫入到物理裝置,比如磁碟 |
下面幾個為InputStream獨有
public int available() throws IOException 返回此輸入流下一個方法呼叫可以不受阻塞地從此輸入流讀取(或跳過)的估計位元組數 這句話有些繞口,直白的說就是: 在方法呼叫前,可以獲取到這個流中可用的位元組數目 假設說有N個位元組可以使用,顯然你應該很可能讀取到N個位元組,或者能夠跳過N個位元組 一次讀取或跳過此估計數個位元組不會受阻塞 |
注意: 這個數目是一個預估的數量 實際的讀取或者跳過的位元組數可能小於這個數 |
InputStream中的這個方法總是返回0 所以這個方法能否使用依賴於子類的實現 InputStream中的這個方法總是返回0 |
public long skip(long n) throws IOException |
返回的是實際跳過的位元組數 在內部建立一個 byte 陣列,然後重複將位元組讀入其中,直到讀夠 n 個位元組或已到達流末尾為止 |
reset() mark(int) markSupported() 三個方法是對於同一個功能點的不同方法 ,可以解決重複讀的問題 |
mark(int)用來在此輸入流中做標記,標記當前位置 打一個書籤 markSupported() 測試此輸入流是否支援 mark 和 reset 方法 reset() 將此流重新定位到最後一次對此輸入流呼叫 mark 方法時的位置 回到書籤 |
看下類中的預設程式碼可以發現: 預設情況下mark什麼都不做 markSupported直接返回false reset方法的呼叫會丟擲異常 |
mark的引數用於告知輸入流在標記位置失效之前允許讀取的位元組數 |
標記已關閉的流對其無效 |
說起來很迷惑,用起來卻很簡單 比如 xxxStream.mark(50);//表明系統至少應該緩衝50以上個數據,以保證可以回來重新讀取 xxxStream.read(); ..... xxxStream.read(); xxxStream.reset();//reset之後,讀取到的資料將會和剛才呼叫mark 方法後read的資料是相同的 xxxStream.read(); ..... xxxStream.read(); |
如果方法 markSupported 返回 true,那麼輸入流總是在呼叫 mark 之後記錄所有讀取的位元組 並時刻準備在呼叫方法 reset 時(無論何時),再次提供這些相同的位元組 但是,如果在呼叫 reset 之前可以從流中讀取多於 readlimit 的位元組,則不需要該流記錄任何資料 |