I/O:輸入輸出系統,由輸入輸出控制系統和外圍設備兩部分組成。java
Java中I/O操做主要是指使用Java進行輸入,輸出操做. Java全部的I/O機制都是基於數據流進行輸入輸出,這些數據流表示了字符或者字節數據的流動序列。java類庫中的I/O類分爲輸入和輸出兩部分。數組
Java IO模型 :Java的IO模型設計是很是典型的裝飾器模式---Decorator模式,按功能劃分Stream,能夠動態裝配這些Stream,以便得到您須要的功能。例如,須要一個具備緩衝的文件輸入流,則應當組合使用FileInputStream和BufferedInputStream。緩存
1.按流的方向分類架構
按流的方向分爲:輸入和輸出流,注意輸入流和輸出流是相對於程序而言的。輸入流即從不一樣數據源輸入進程序或者說內存。輸出流則相反。編碼
輸入流的數據源包括:字節數組、String對象、文件、管道、一個由其餘種類的流組成的序列、其餘數據源,如intenet鏈接等。spa
2.按傳輸單位分類設計
按傳輸單位分爲:字節流和字符流,例如:InputStream和OutStream、Reader和Writer。code
輸入/輸出視頻 |
字節流對象 |
字符流 |
輸入流 |
Inputstream |
Reader |
輸出流 |
OutputStream |
Writer |
3.按功能分類
按功能分爲:節點流和處理流,節點流:能夠從或向一個特定的地方(節點)讀寫數據。如FileReader。處理流:是對一個已存在的流的鏈接和封裝,經過所封裝的流的功能調用實現數據讀寫。如BufferedReader。
從網上找到一張關於java IO流的總體架構圖,一目瞭然。
1 public class FileStreamDemo { 2 3 public static void main(String[] args) { 4 5 //字節輸入/輸出流,而且以文件爲數據源,即文件字節輸入輸出流 6 try { 7 //1.肯定數據源與流類型 8 File targetFile = new File("E:\\a.txt"); 9 OutputStream os = new FileOutputStream(targetFile, true);//第二參數,表示寫入的數據是否追加到文件後面 10 //2.藉助流進行具體的IO操做 11 /** 12 * void write(int b):把一個字節寫入到文件中 13 * void write(byte[] b):把數組b 中的全部字節寫入到文件中 14 * void write(byte[] b,int off,int len):把數組b 中的從 off 索引開始的 len 個字節寫入到文件中 15 */ 16 os.write(45); 17 os.write("aaa".getBytes()); 18 os.write("bbbbb".getBytes(), 1, 3); 19 //操做完畢,關閉流 20 os.close(); 21 22 //經過字節輸入流將目標文件的數據讀取進內存中 23 InputStream is = new FileInputStream(targetFile); 24 25 //讀取一個字節 26 int data1 = is.read(); 27 System.out.println((char)data1); 28 29 byte [] bytes = new byte[10]; 30 is.read(bytes); 31 System.out.println(Arrays.toString(bytes)); 32 33 is.close(); 34 35 36 37 } catch (Exception e) { 38 e.printStackTrace(); 39 } 40 41 42 43 } 44 45 }
結果輸出:
- [97, 97, 97, 98, 98, 98, 0, 0, 0, 0]
Java中字符是採用Unicode標準,一個字符是16位,即一個字符使用兩個字節來表示。爲此,JAVA中引入了處理字符的流。通常能夠用記事本打開的文件,咱們能夠看到內容不亂碼的。就是文本文件,可使用字符流。而操做二進制文件(好比圖片、音頻、視頻)必須使用字節流。
1 public class FileStreamDemo2 { 2 3 public static void main(String[] args) { 4 //1.定義數據源對象 5 File targetFile = new File("E:\\test.txt"); 6 try { 7 //2.定義輸出字符流 8 FileWriter fw = new FileWriter(targetFile,true); 9 //3.藉助字符流進行IO操做 10 fw.write(65); 11 fw.write("lplp"); 12 fw.write(new char[]{'a','b','c'}, 1, 2); 13 fw.close(); 14 15 FileReader fr = new FileReader(targetFile); 16 char [] ch= new char[5]; 17 System.out.println(fr.read()); 18 int count = fr.read(ch);//讀取流中字符填充到字符數組ch中 19 System.out.println(count+":"+Arrays.toString(ch)); 20 fr.close(); 21 } catch (Exception e) { 22 e.printStackTrace(); 23 } 24 } 25 26 }
結果輸出:
65 5:[l, p, l, p, b]
包裝流,又稱處理流,主要用來對已存在的流進行修飾和封裝,進一步豐富或拓展流的功能。經常使用的處理流主要有下面幾種
緩衝流:是一個包裝流,目的是緩存做用,加快讀取和寫入數據的速度。
字節緩衝流:BufferedInputStream、BufferedOutputStream
字符緩衝流:BufferedReader、BufferedWriter
1 public class BufferStreamDemo { 2 3 public static void main(String[] args) { 4 5 //1.定義數據源對象 6 File targetFile = new File("E:\\test2.txt"); 7 8 try { 9 //2.定義字節緩衝輸出流 10 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(targetFile)); 11 /* 12 *經過緩衝流將字節數組寫入到文件輸出流,最終是寫入到文件,與經過文件字節輸出流的區別在於,具有一個緩衝的做用,並不會當即將字節數組或者字節 13 * 寫入到文件中,而先將字節寫入到緩衝字節數組中,最後一次性寫入到輸出流中,避免屢次操流,減小IO操做,提升效率,寫到內存中比寫到硬盤上快的多 14 */ 15 bos.write("aaa".getBytes()); 16 bos.write(100); 17 bos.write("sdjlksdjkl".getBytes(), 1, 5); 18 19 bos.flush();//將緩衝字節數組的字節寫入文件 20 bos.close(); 21 //3.定義字節緩衝輸入流,本質上也是較少IO操做 22 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(targetFile)); 23 24 System.out.println((char)bis.read()); 25 byte [] bs = new byte[8]; 26 bis.read(bs); 27 System.out.println(Arrays.toString(bs)); 28 System.out.println(new String(bs)); 29 30 bis.close(); 31 } catch (Exception e) { 32 e.printStackTrace(); 33 } 34 35 } 36 37 }
結果輸出:
a
[97, 97, 100, 100, 106, 108, 107, 115]
aaddjlks
字符緩衝流,BufferedReader和BufferedWriter的使用和上面殊途同歸。
InputStreamReader:把字節輸入流轉換爲字符輸入流
OutputStreamWriter:把字節輸出流轉換爲字符輸出流
1 public class BufferStreamDemo2 { 2 3 public static void main(String[] args) { 4 5 //1.定義數據源對象 6 File targetFile = new File("E:\\test2.txt"); 7 8 try { 9 //定義緩衝字符流,將字節輸出流轉換爲字符流,再包裝爲字符輸出緩衝流,而且字符在轉字節的時候,採用的編碼爲UTF-8 10 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetFile),"UTF-8")); 11 bw.write("aaabababcc"); 12 bw.flush(); 13 bw.close(); 14 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(targetFile))); 15 String line = br.readLine();//讀取文件中的一行 16 System.out.println(line); 17 br.close(); 18 19 } catch (Exception e) { 20 e.printStackTrace(); 21 } 22 23 } 24 25 }
結果輸出:
aaabababcc
字節內存流:ByteArrayOutputStream 、ByteArrayInputStream
字符內存流:CharArrayReader、CharArrayWriter
字符串流:StringReader,StringWriter(把數據臨時存儲到字符串中)
1 public class ArrayStreamDemo { 2 3 public static void main(String[] args) { 4 //1.字節內存流,數據源爲字節數組 5 ByteArrayInputStream bais = new ByteArrayInputStream("aaa".getBytes()); 6 //2經過字節流從字節數組從讀取字節 7 int len =-1; 8 while((len=bais.read())!=-1){ 9 System.out.println((char)len); 10 } 11 //3.定義字節數組輸出流 12 ByteArrayOutputStream baos = new ByteArrayOutputStream(5);//10表示指定字節數組的大小 13 try { 14 baos.write("abcdef".getBytes()); 15 16 System.out.println(Arrays.toString(baos.toByteArray())); 17 System.out.println("--------------"); 18 //4.定義字符數組輸出流 19 CharArrayWriter caw = new CharArrayWriter(); 20 caw.write("ppll"); 21 System.out.println(new String(caw.toCharArray())); 22 //5.定義字符數組輸入流 23 CharArrayReader car = new CharArrayReader(caw.toCharArray());//從字符數組中讀取字符 24 int len2 =-1; 25 while((len2=car.read())!=-1){ 26 System.out.print((char)len2); 27 } 28 System.out.println(); 29 System.out.println("--------------"); 30 //7.字符串輸入流 31 StringReader sr = new StringReader("aaaa"); 32 //8.字符串輸出流 33 StringWriter sw = new StringWriter(); 34 int len3=-1; 35 while((len3=sr.read())!=-1){ 36 sw.write(len3); 37 } 38 System.out.println(sw.getBuffer().toString()); 39 40 } catch (Exception e) { 41 e.printStackTrace(); 42 } 43 44 45 } 46 47 }
輸出結果:
a a a [97, 98, 99, 100, 101, 102] -------------- ppll ppll -------------- aaaa