I/O流
定義
數據從硬盤流向內存為輸入流,數據從內存流向硬盤為輸出流。輸入也叫讀取數據,輸出也叫寫出數據。
IO分類
1.按照數據的流向分為:輸入流和輸出流
①輸入流:把數據從其他設備上讀取到內存中的流
②輸出流:把數據從內存中寫出到其他設備上的流
2.按照功能類型分為:字節流和字符流
①字節流:以字節為單位,讀寫數據的流
②字符流:以字符為單位,讀寫數據的流
字節流和字符流的頂級父類
字節流:①字節輸入流:InputStream
②字節輸出流:OutputStream
字符流:①字符輸入流:Reader
②字符輸出流:Writer
注:這些都是抽象父類,不能直接使用,要使用他們的子實現類
字節輸出流(OutputStream)
一切皆為字節,我們存儲的數據,文件,圖片等都是以二進制數字的形式保存,都是一個一個的字節,傳輸的時候也是一樣。java.io.OutputStream抽象類是表示字節輸出流的所有類的父類,將指定的字節信息寫出到目的地。
1.字節輸出流的基本共性功能方法:
①public void close():關閉此輸出流并釋放與此流相關聯的任何系統資源當完成流的操作時,必須調用此方法,釋放系統資源。
②public void write(byte[] b):將 b.length字節從指定的字節數組寫入此輸出流。
③public void write(byte[] b, int off, int len)` :從指定的字節數組寫入 len字節,從偏移量 off開始輸出到此輸出流。
④public abstract void write(int b):將指定的字節輸出。
FileOutputStream類(文件字節輸出流)
OutputStream的子類,用于將數據寫出到文件
構造方法
1.public FileOutputStream(File file):創建文件輸出流以寫入由指定的File對象表示的文件
// 使用File對象創建流對象File file = new File("a.txt");FileOutputStream fos = new FileOutputStream(file);
2.public FileOutputStream(String name):創建文件輸出流以指定的名稱寫入文件
// 使用文件名稱創建流對象FileOutputStream fos = new FileOutputStream("b.txt");
注:如果目標文件不存在,則創建,若存在,則覆蓋。
常用方法:
1.寫出字節:write(int b) 方法,每次可以寫出一個字節數據
FileOutputStream fos = new FileOutputStream(“D:/test/test.txt”);fos.write(97);fos.close();//文件中會寫出a
注:雖然參數為int類型四個字節,但是只會保留一個字節的信息寫出,因為這是字節輸出流,一個字節一個字節輸出,只會保留我們輸出的那個字節。
2.寫出字節數組:write(byte[] b),每次可以寫出數組中的數據
File file = new File("D:/test/test.txt");FileOutputStream fos = new FileOutputStream(file);//寫出一個字節數組大小的數據byte[] b={97,98,99,100};fos.write(b);byte[] b1="今天真好看".getBytes();fos.write(b1);fos.close();//寫入abcd今天真好看
3.寫出指定長度字節數組:write(byte[] b, int off, int len),每次寫出從off索引開始,len個字節
File file = new File("D:/test/test.txt");FileOutputStream fos = new FileOutputStream(file);//寫出數組中指定長度的字節數據byte[] b={97,98,99,100};fos.write(b,1,2);fos.close();//寫入bc
4.數據追加續寫
public FileOutputStream(File file/String name,boolean append):這個構造方法,參數中需要傳入一個boolean類型的值,true表示追加數據,false表示清空原有數據,不寫的話默認是false
File file = new File("D:/test/test.txt");FileOutputStream fos = new FileOutputStream(file,true);//追加數據byte[] b={97,98,99,100};fos.write(b,1,2);fos.close();//寫入bcbc
5.寫出換行
File file = new File("D:/test/test.txt");FileOutputStream fos = new FileOutputStream(file,true);//換行\r\nbyte[] b={97,98,99,100};for(int i:b){fos.write(i);fos.write("\r\n".getBytes());}fos.close();
注:①回車符(\r):回到一行的開頭,如果在abcde中的c前回車后不做任何操作,再寫數據的時候光標是在c前面
???????②換行符(\n):另起一行,如果在abcde中的c前換行后不做任何操作,再寫數據的時候光標是在e后面
字節輸入流(InputStream)
java.io.InputStream 抽象類是表示字節輸入流的所有類的父類,可以讀取字節信息到內存中。定義了字節輸入流的基本共性功能方法。
1.基本共性功能方法:
①public void close():關閉此輸入流并釋放與此流相關聯的任何系統資源。
②public abstract int read(): 從輸入流讀取數據的下一個字節。
③public int read(byte[] b): 從輸入流中讀取一些字節數,并將它們存儲到字節數組 b中 。
FileInputStream類(文件字節輸入流)
構造方法:
1.FileInputStream(File file): 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的 File對象 file命名。
// 使用File對象創建流對象File file = new File("a.txt");FileInputStream fos = new FileInputStream(file);
2.public FileInputStream(String name):通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的路徑名 name命名。
// 使用文件名稱創建流對象FileInputStream fos = new FileInputStream("b.txt");
常用方法:
1.讀取字節數據:read方法,從輸入流中讀取數據的下一個字節,自動提升為int類型,讀取到文件末尾,返回-1。
public static void main(String[] args) throws IOException {File file=new File("D:\\test\\test.txt");FileInputStream fis = new FileInputStream(file);int r;while ((r=fis.read())!=-1){System.out.println((char)r);//遍歷文件中的全部字節}fis.close();}
2.使用字節數組讀取:read(byte[] b),每次讀取b的長度個字節到數組中,返回讀取到的有效字節個數,讀取到末尾時,返回-1。
public static void main(String[] args) throws IOException {File file=new File("D:\\test\\test.txt");FileInputStream fis = new FileInputStream(file);//每次讀一個字節數組的數據byte[] b=new byte[3];int read =fis.read(b);//返回的int值是讀取的有效字節個數System.out.println(read);//3System.out.println(new String(b));//bcafis.close();}
注:
讀取到的數據賦值給字節數組b,每一次讀取會覆蓋前一次的數據如果字符的長度不是字節數組的整數倍,比如字節數組長度為3,但是讀取到最后只剩2個字符,那么這兩個字符會覆蓋字符數組前兩位,而第三位則還是上一次讀取的字符,
改進如下:
public static void main(String[] args) throws IOException {File file=new File("D:\\test\\test.txt");FileInputStream fis = new FileInputStream(file);byte[] b=new byte[3];//定義有效字節數int len;while ((len=fis.read(b))!=-1){String s=new String(b,0,len);System.out.println(s);}fis.close();}
字符輸入流(Reader)
java.io.Reader抽象類是表示用于讀取字符流的所有類的父類,可以讀取字符信息到內存中。
1.基本共性功能方法:
①public void close():關閉此流并釋放與此流相關聯的任何系統資源
②public int read(): 從輸入流讀取一個字符
③public int read(char[] cbuf): 從輸入流中讀取一些字符,并將它們存儲到字符數組 cbuf中
FileReader類
java.io.FileReader `類是讀取字符文件的便捷類
構造方法:
①FileReader(File file): 創建一個新的 FileReader ,給定要讀取的File對象
// 使用File對象創建流對象File file = new File("a.txt");FileReader fr = new FileReader(file);
②FileReader(String fileName): 創建一個新的 FileReader ,給定要讀取的文件的名稱
// 使用文件名稱創建流對象FileReader fr = new FileReader("b.txt");
常用方法:
1.讀取字符:read方法,每次可以讀取一個字符的數據,提升為int類型,讀取到文件末尾,返回-1,循環讀取
public static void main(String[] args) throws IOException {//字符輸入流FileReader fr=new FileReader(new File("F:\\test\\bbb.txt"));int r ;while ((r=fr.read())!=-1){System.out.println((char)r);}fr.close();}
2.使用字符數組讀取:read(char[] cbuf),每次讀取b的長度個字符到數組中,返回讀取到的有效字符個數,讀取到末尾時,返回-1
public static void main(String[] args) throws IOException {//字符輸入流FileReader fr=new FileReader(new File("F:\\test\\bbb.txt"));char[] c=new char[3];int l;while ((l=fr.read(c))!=-1){String s=new String(c,0,l);System.out.println(s);}fr.close();}
字符輸出流(Writer)
java.io.Writer 抽象類是表示用于寫出字符流的所有類的超類,將指定的字符信息寫出到目的地
1.基本共性功能方法
①public abstract void close():關閉此輸出流并釋放與此流相關聯的任何系統資源
②public abstract void flush():刷新此輸出流并強制任何緩沖的輸出字符被寫出
③public void write(int b):寫出一個字符
④public void write(char[] cbuf):將 cbuf.length字符從指定的字符數組寫出此輸出流
⑤public abstract void write(char[] b, int off, int len):從指定的字符數組寫出 len字符,從偏移量 off開始輸出到此輸出流
⑥public void write(String str):寫出一個字符串
FileWriter類
java.io.FileWriter 類是寫出字符到文件的便利類。構造時使用默認字節緩沖區(之前輸出流是從內存直接就寫到硬盤中了,現在這個字符輸出流是有一個緩沖區存在的,在向外界磁盤寫數據的時候會先把數據寫到緩沖區中,只有調用刷新或者關閉方法的時候,才會把當前緩沖區內的數據輸出到指定文件中)
構造方法:
1.FileWriter(File file): 創建一個新的 FileWriter,給定要讀取的File對象
// 使用File對象創建流對象File file = new File("a.txt");FileWriter fw = new FileWriter(file);
2.FileWriter(String fileName): 創建一個新的 FileWriter,給定要讀取的文件的名稱
// 使用文件名稱創建流對象FileWriter fw = new FileWriter("b.txt");
常用方法:
1.寫出字符:write(int b) 方法,每次可以寫出一個字符數據
public static void main(String[] args) throws IOException {//文件字符輸出流//FileWriter fw= new FileWriter("F:\\test\\aaa.txt");FileWriter fw= new FileWriter(new File("F:\\test\\aaa.txt"));fw.write("我");fw.write(30000);//寫出的數據現在存放在緩沖區中,必須刷新或者關閉才能把數據輸出到文件中。fw.close();}
關閉和刷新的區別
1.flush:刷新緩沖區,流對象可以繼續使用
2.close:關閉流,釋放系統資源,關閉前會刷新緩沖區,但流對象不可以繼續使用。
public static void main(String[] args) throws IOException {// 使用文件名稱創建流對象FileWriter fw = new FileWriter("F:\\test\\aaa.txt");// 寫出數據,通過flushfw.write('刷'); // 寫出第1個字符fw.flush();//寫出成功fw.write('新'); // 繼續寫出第2個字符fw.flush();//寫出成功// 寫出數據,通過closefw.write('關'); // 寫出第1個字符fw.close();fw.write('閉'); // 繼續寫出第2個字符,【報錯】java.io.IOException: Stream closedfw.close();}
2.寫出其他數據
①寫出字符數組?:write(char[] cbuf) 和 write(char[] cbuf, int off, int len),每次可以寫出字符數組中的數據,同FileOutputStream的用法一樣。
FileWriter fw= new FileWriter(new File("F:\\test\\aaa.txt"));char[] c="今天適合吹風".toCharArray();fw.write(c);fw.write(c,3,2);//寫出的數據現在存放在緩沖區中,必須刷新或者關閉才能把數據輸出到文件中。fw.close();
②寫出字符串:write(String str) 和 write(String str, int off, int len),每次可以寫出字符串中的數據。
FileWriter fw= new FileWriter(new File("F:\\test\\aaa.txt"));String s="今天太陽好大";fw.write(s);fw.write(s,2,3);//寫出的數據現在存放在緩沖區中,必須刷新或者關閉才能把數據輸出到文件中。fw.close();
③續寫和換行:操作類似于FileOutputStream
FileWriter fw= new FileWriter(new File("F:\\test\\aaa.txt"),true);fw.write("今天太陽好大");fw.write("\r\n");fw.write("今天");//寫出的數據現在存放在緩沖區中,必須刷新或者關閉才能把數據輸出到文件中。fw.close();
總結
凡是自己能寫出來的用字符流,字符寫不出來的比如圖片,視頻等用字節流。
IO流的異常處理
第一種方式:
public static void main(String[] args){FileInputStream fis=null;FileOutputStream fos=null;try{fis=new FileInputStream("C:\\test\\完整的頁面效果圖.jpg");fos=new FileOutputStream("C:\\test\\1.jpg");byte[] b=new byte[1024];int l=0;while((l=fis.read(b))!=-1){fos.write(b,0,l);}}catch(IOException e){e.printStackTrace();}finally {try {if(fos!=null){fos.close();}} catch (IOException e) {e.printStackTrace();}try {if(fis!=null){fis.close();}} catch (IOException e) {e.printStackTrace();}}}
第二種方式:1.7之后流的簡化版處理異常的方式.不再需要自己關流,這種方式會自動關流
public static void main(String[] args) throws IOException {//第二種方式try(FileInputStream fis=new FileInputStream("C:\\test\\完整的頁面效果圖.jpg");FileOutputStream fos=new FileOutputStream("C:\\test\\1.jpg")){byte[] b=new byte[1024];int l=0;while((l=fis.read(b))!=-1){fos.write(b,0,l);}}catch (Exception e){e.printStackTrace();}}