在計算機術語中,I/O(input/output)是系統和外部進行交流通訊的方式。輸入(input)是系統收到的信號或者數據,輸出是系統對外發出的信號或者數據。咱們一般所說的執行I/O操做就是對於輸入或者輸出數據的處理。java
Java IO是Java提供的一系列用於處理輸入和輸出數據的API。Java對於輸入和輸出進行了抽象,用流(Stream)來表示輸入輸出。流能夠表明任何類型的輸入源或者輸出目標。好比硬盤上的文件,內存,其餘設備等。 流由一系列的數據組成,你能夠把流想象成水流,程序可使用輸入流來讀取數據,使用輸出流來寫出數據。流支持不一樣類型的數據,如字節數據,基本類型數據,對象等數組
從流中讀取數據 緩存
向流中寫入數據 性能
Java Stream中根據處理數據的最小單位不一樣,能夠分爲字節流和字符流兩種。編碼
字節流操作系統
數據流中最小的數據單元是字節線程
字符流 數據流中最小的數據單元是字符, Java中的字符是Unicode編碼,一個字符佔用兩個字節。3d
根據這兩種不一樣的類型,Java提供了一些列的Java類code
InputStream是全部字節輸入流的基類,提供了讀取字節流的基本方法,其子類經過繼承InputStream實現不一樣形式的字節流。咱們先看下InputStream中的關鍵方法cdn
方法 | 方法介紹 |
---|---|
public abstract int read() | 從流中讀取一個字節數據,抽象方法由子類負責實現真正的讀取 |
public int read(byte b[]) | 從流中讀取數組長度的字節數據,內部調用下面的方法實現 |
public int read(byte b[], int off, int len) | 從流中讀取len個字節,寫入到從off位置開始的數組中 |
public long skip(long n) | 跳過流中的幾個字節 |
public int available() | 流中可讀字節的數量 |
public void close() | 關閉字節流,釋放系統資源 |
public synchronized void mark(int readlimit) | 標記當前位置,調用reset方法以後還能夠從當前位置開始讀取,調用前須要經過markSupported檢查實現類四是否支持mark |
public synchronized void reset() | 重置讀取位置爲上次 mark 標記的位置 |
public boolean markSupported() | 判斷當前流是否支持標記流 |
ByteArrayInputStream把一個數組包裝成輸入流,從字節數組讀取數據。相比於直接使用原始數組,ByteArrayInputStream提供了read-only功能。由於流沒有提供更改數組內容的方法。
FileInputStream從文件系統中讀取字節數據,是咱們使用比較多的一個類,內部實際讀取文件內容的方法爲native方法實現,通常讀取配置包裝類BufferedInputStream使用,減小I/O消耗。
PipedInputStream主要用戶線程間通訊,PipedInputStream鏈接到PipedOutputStream,一個線程經過PipedOutputStream寫數據,另一個經過PipedInputStream讀取數據。可是線程間通訊也能夠採起共享內存到方式。因此使用過程當中應用場景很少。
咱們都知道Java IO包使用了經典的裝飾模式,經過裝飾器增長原始輸入輸出流的功能。FilterInputStream是輸入裝飾器的基類,自己沒有提供特殊的功能,只是簡單的把調用轉發到原始輸入流中。具體裝飾器經過實現類來擴展。
BufferedInputStream
BufferedInputStream是咱們使用比較多的類,提供了讀取輸入的緩存功能,經過一次讀取和緩存多個字節的數據到內存中,減小系統調用帶來的開銷。可是要注意的是並非任何狀況下經過BufferedInputStream都能提升讀取的性能,經過閱讀源碼能夠發現,BufferedInputStream默認讀取8K(8192)的緩存數據,若是你一次讀取的字節超過了緩存大小的數據,反而增長了一次數據的內存拷貝,下降了程序的性能。因此須要根據自身程序特色決定是否使用。
PushbackInputStream
回退流,咱們的輸入流在只能順序的從前日後讀取字節,PushbackInputStream提供了回退功能,把讀取進來不須要的字節回退到輸入流的緩存中。
DataInputStream
DataInputStream提供了咱們從輸入流中讀取Java基本數據類型數據的功能。根據數據類型字節長度不一樣,讀取相應的字節,轉換爲咱們須要的基本數據類型。好比int類型,讀取流中的四個字節,經過移位的方式組合成咱們須要的int類型數據。
ObjectInputStream用於對象的反序列化,從流中讀取數據,轉換爲咱們須要的Java對象。對象反序列化的過程不包括transient和靜態字段。可反序列化的對象必須實現Serializable接口。
OutputStream是全部字節輸出流的基類,提供了寫出數據的基本方法,其子類經過繼承OutputStream實現不一樣形式的字節輸出流。咱們先看下OutputStream中的關鍵方法
方法 | 方法介紹 |
---|---|
public abstract void write(int b) | 向輸出流中寫入一個字節,取的是int的低八位字節 |
public void write(byte b[]) | 向輸出流中寫入字節數組 |
public void write(byte b[], int off, int len | 向輸出流中寫入len長度的字節數據,從b[]的off位置開始 |
public void flush() | 強制刷新,將緩衝中的數據寫入的輸出流。這裏只是保證寫入到輸出流,,好比文件,只是保證寫入到操做系統緩存。 |
public void close() | 關閉字節流,釋放系統資源 |
ByteArrayOutputStream寫入到內存中的字節數組緩存中,數組大小會隨着寫入數量的增長而自動增加。能夠經過toByteArray或者toString獲取寫入的數據
FileOutputStream寫入字節到文件中
PipedOutputStream管道輸出流須要和PipedOutputStream配合使用,用於線程間通訊。
FilterOutputStream和FilterInputStream相似,是輸出字節流的裝飾類的基類,自己沒有提供特殊的功能,只是簡單的把調用轉發到原始輸入流中。具體裝飾器經過實現類來擴展。
ObjectOutputStream用於對象的序列化,把Java對象對象寫入到輸出流中。對象序列化的過程不包括transient和靜態字段。可序列化的對象必須實現Serializable接口。
字符流和字節流相似,基本的類結構和方法和字節流也基本相同。不一樣過的是字符流讀取的單位是字符,而字節流是單個字節。須要注意的是FileReader和FileWriter,不是直接繼承的Reader和Writer抽象類,而是經過OutputStreamReader和OutputStreamWriter進行橋接,底層依然使用的FileInputStream和FileOutputStream。
原文地址: blog.devlab.cn/java-io/#mo…