什麼是IO流?
Java中I/O操做主要是指使用java.io包下的內容,進行輸入、輸出操做。輸入也叫作讀取數據,輸出也叫作做寫出數據。java
輸入輸出(IO): 輸入輸出是指計算機同任何外部設備之間的數據傳遞。數組
在IO流裏,輸入輸出分爲4步:格式化/解析,緩衝,編碼轉換和傳遞。緩存
格式化/解析:在內部數據表示(以字節爲單位)與外部數據表示(以字符爲單位)之間進行雙向轉換。例如一個2字節的整數10002,就須要5個字符來表示。編碼
緩衝:用於在格式/解析與傳遞之間緩存字符序列。對於輸出,較短的字符序列格式化以後並不立刻輸出,而是保存在緩衝區裏,待累積到必定規模以後再傳遞到外部設備。相反,從外部設備讀入的大量數據也是先放在緩衝區,而後逐步取出完成輸入。默認時,IO流的輸入輸出都是通過緩衝的,也可讓IO流工做在無緩衝模式下。線程
編碼轉換:是將一種字符表達式轉換成另外一種字符表達式。若是格式化產生的字符表達式與外部字符表達式不一樣(輸出時),或者外部表達式與IO流能解析的表達式不一樣(輸入時),就必須進行編碼轉換。如多字節編碼與寬字符編碼之間的轉換等。多數狀況下並不須要進行編碼轉換。code
傳遞:主要是與外部設備進行通訊。輸出時,傳遞負責將通過格式化、緩衝即編碼轉換後的字符序列發送到外部設備;輸入時,則負責將外部設備抽取數據,爲其後進行的編碼轉換、緩衝及解析提供字符序列。對象
IO流的分類:
根據數據的流向分爲:圖片
- 輸入流 :把數據從其餘設備上讀取到內存中的流,只能進行讀操做。
- 輸出流 :把數據從內存 中寫出到其餘設備上的流,只能進行寫操做。
根據數據的類型分爲:ip
- 字節流 :以字節爲單位,讀寫數據的流。
- 字符流 :以字符爲單位,讀寫數據的流。
字節流和字符流的區別:內存
- 讀寫單位不一樣:字節流以字節爲單位,字符流以字符爲單位
- 處理對象不一樣:字節流能處理全部類型的數據(如圖片、avi等),而字符流只能處理字符類型的數據。
- 字節流:一次讀入或讀出是8位二進制。
- 字符流:一次讀入或讀出是16位二進制。
分類以後對應的超類(超類也就是父類的意思) | | 輸入流 | 輸出流 |--|--|--| | 字節流 | 字節輸入流 InputStream |字節輸出流 OutputStream | | 字符流 | 字符輸入流 Reader|字符輸出流 Writer|
注: 由這四個類的子類名稱基本都是以其父類名做爲子類名的後綴。
字節輸入流 InputStream:
InputStream
是全部的字節輸入流 的父類,它是一個抽象類。ByteArrayInputStream
、StringBufferInputStream
、FileInputStream
是三種基本的介質流,它們分別從Byte 數組
、StringBuffer
、和本地文件
中讀取數據。PipedInputStream
是從與其它線程共用的管道中讀取數據。ObjectInputStream
和全部FilterInputStream
的子類都是裝飾流(裝飾器模式的主角)。
FileInputStream fis = new FileInputStream("xxx.txt");//建立流對象 int b; while((b = fis.read()) != -1) { //字節輸入流對象fis一次讀一個字節 並賦值給b 判斷b是否是-1 System.out.println(b); } fis.close();
字節輸出流 OutputStream:
OutputStream
是全部的字節輸出流 的父類,它是一個抽象類。ByteArrayOutputStream
、FileOutputStream
是兩種基本的介質流,它們分別向Byte 數組
、和本地文件
中寫入數據。PipedOutputStream
是向與其它線程共用的管道中寫入數據。ObjectOutputStream
和全部FilterOutputStream
的子類都是裝飾流。
FileOutputStream fos = new FileOutputStream("yyy.txt"); fos.write(100); //寫出的是一個int數,可是到文件上的是一個字節,會自動去除前三個8位 fos.write(99); //此時文件yyy.txt中是 dc fos.close();
注意:
1)輸出流輸出數據在建立輸出流對象的時候,若是不存在文件,就建立一個;若是存在就清空該文件數據,而後寫入數據。 2)若是想在文件裏面追加寫入就用new FileOutputStream(String pathName,true)這個構造方法。
字符輸入流:
public int read():讀取單個字符,並返回成int,若是已到達流的末尾,則返回 -1 public int read(char[] cbuf):將字符讀入數組,返回讀取的字符數,若是已到達流的末尾,則返回 -1
public static void main(String[] args) throws IOException { FileReader fr = new FileReader("xxx.txt"); //建立字符輸入流對象 int c; while((c = fr.read()) != -1) { //經過項目默認的碼錶一次讀取一個字符 System.out.print((char)c); //將c強制類型轉換成char } fr.close(); }
字符輸出流:
public void write(int c):寫入單個字符。 public void write(char[] cbuf):寫入字符數組。 public abstract void write(char[] cbuf,int off, int len):寫入字符數組的某一部分。cbuf - 字符數組,off - 開始寫入字符處的偏移量,len - 要寫入的字符數。 public void write(String str):寫入字符串。 public void write(String str,int off, int len):寫入字符串的某一部分。str - 字符串,off - 相對初始寫入字符的偏移量,len - 要寫入的字符數 。
節點流: 直接與數據源相連,讀入或讀出。
經常使用的節點流:
- 父 類 :
InputStream
、OutputStream
、Reader
、Writer
- 文 件 :
FileInputStream
、FileOutputStrean
、FileReader
、FileWriter
文件進行處理的節點流 - 數 組 :
ByteArrayInputStream
、ByteArrayOutputStream
、CharArrayReader
、CharArrayWriter
對數組進行處理的節點流(對應的再也不是文件,而是內存中的一個數組) - 字符串 :
StringReader
、StringWriter
對字符串進行處理的節點流 - 管 道 :
PipedInputStream
、PipedOutputStream
、PipedReader
、PipedWriter
對管道進行處理的節點流
處理流: 處理流和節點流一塊使用,在節點流的基礎上,再套接一層,套接在節點流上的就是處理流。
經常使用的處理流:
- 緩衝流:
BufferedInputStrean
、BufferedOutputStream
、BufferedReader
、BufferedWriter
增長緩衝功能,避免頻繁讀寫硬盤。 - 轉換流:
InputStreamReader
、OutputStreamReader
實現字節流和字符流之間的轉換。 - 數據流:
DataInputStream
、DataOutputStream
等-提供將基礎數據類型寫入到文件中,或者讀取出來。
轉換流: InputStreamReader
、OutputStreamWriter
要InputStream
或OutputStream
做爲參數,實現從字節流到字符流的轉換。
序列流: 序列流能夠把多個字節輸入流整合成一個, 從序列流中讀取數據時, 將從被整合的第一個流開始讀, 讀完一個以後繼續讀第二個, 以此類推。
1)整合兩個輸入流SequenceInputStream(InputStream s1, InputStream s2);
public static void demo2() throws FileNotFoundException, IOException { FileInputStream fis1 = new FileInputStream("a.mp3"); FileInputStream fis2 = new FileInputStream("b.mp3"); SequenceInputStream sis = new SequenceInputStream(fis1, fis2); FileOutputStream fos = new FileOutputStream("c.mp3"); //歌曲串燒,c.mp3裏面有a.mp3和b.mp3兩首歌 int b; while((b = sis.read()) != -1) { fos.write(b); } sis.close(); //sis在關閉的時候,會將構造方法中傳入的流對象也都關閉 fos.close(); }
2)整合多個輸入流 SequenceInputStream(Enumeration<? extends InputStream> e)
public static void main(String[] args) throws IOException { FileInputStream fis1 = new FileInputStream("a.txt"); FileInputStream fis2 = new FileInputStream("b.txt"); FileInputStream fis3 = new FileInputStream("c.txt"); Vector<FileInputStream> v = new Vector<>(); //建立集合對象 v.add(fis1); //將流對象存儲進來 v.add(fis2); v.add(fis3); Enumeration<FileInputStream> en = v.elements(); SequenceInputStream sis = new SequenceInputStream(en); //將枚舉中的輸入流整合成一個 FileOutputStream fos = new FileOutputStream("d.txt"); int b; while((b = sis.read()) != -1) { fos.write(b); } sis.close(); fos.close(); }