Java中的IO流(一)
一,IO流的分類
A,按照操作的物件不同可分為位元組流與字元流
B,按照流的方向不同可分為輸入(指從外部儲存裝置拿檔案到記憶體)流也叫讀與輸出(指從記憶體把檔案寫入到外部儲存裝置)流也叫寫
注:位元組流可以操作任何型別的檔案,字元流是後來才出現的,主要用來操作字元類的檔案;字元流的出現源於編碼表的問題,一開始計算機內使用ANSII編碼,後來每種語言都有了自己的編碼方式即編碼表,為了統一這些編碼資訊國際標準化組織便產生了Unicode編碼資訊表來把世界各國的語言都包括在內,此編碼表採用兩個位元組即16位來儲存每一個字元,java內建的編碼表便是Unicode編碼;字元流是當讀取檔案的時候,以位元組的形式讀取後,查詢編碼表看具體使用哪種編碼方式,查到以後再進行檔案的輸出,所以字元流是位元組流+查編碼表的封裝形式。
二,流的頂層基類
所有流的操作無非兩種形式:讀與寫;所以Java便所這兩種操作形式抽取出了位元組流與字元流的兩種頂層的基類
位元組流的頂層基類:InputStream與OutputStream
字元流的頂層基類:Read與Write
三,字元流FileWriter
1 public static void function_demo1() throws IOException { 2 // 建立字元寫入流物件,接收一個要寫入的檔案路徑物件,此檔案若不存在則新建立一個檔案,若已存在則覆蓋的檔案 3 FileWriter fw = new注:以上程式碼中fw.flush()是把內容從緩衝區刷入到檔案中去,但是fw.close()方法是先把內容從緩衝區刷入到檔案中去即先呼叫flush方法,所以fw.flush()可以不用 FileWrite在寫時的換行與續寫FileWriter("demo1.txt"); 4 fw.write("abcdefg");// 把內容寫入緩衝區 5 fw.flush();// 從緩衝區把內容刷入檔案中 6 fw.close();// 關閉流 7 }
1 // 獲取系統換行的符號 2 privatestatic final String LINE_SEPARATOR = System.getProperty("line.separator"); 3 public static void function_demo2() throws IOException { 4 FileWriter writer = new FileWriter("demo.txt", true);// 建立寫入流物件 5 // 把內容寫入到緩衝區 6 writer.write("abcdef綿" + LINE_SEPARATOR + "中國人啊吼叫職了"); 7 // 把緩衝區裡的內容刷入到檔案系統中 8 // writer.flush(); 9 // 關閉流,在關閉之前會先把緩衝區裡的內容刷入到檔案系統然後才關閉流;若用此關閉流可不用手動呼叫flush 10 writer.close(); 11 }
注:FileWriter在支援續寫的時候提供了一個帶兩個引數的建構函式,當傳遞為true時即可支援續寫;換行可呼叫系統提供的換行符號
四,字元流FileReader1 public static void function_demo3() throws IOException { 2 // 建立讀取流物件,指定需要讀取的檔案地址 3 FileReader reader = new FileReader("demo.txt"); 4 // 宣告一個變數接收讀取到的字元 5 int ch; 6 // 呼叫read方法讀取檔案中的字元,當讀取到檔案的末尾的時候read方法返回-1 7 while ((ch = reader.read()) != -1) { 8 System.out.println((char) ch); 9 } 10 // 關閉流 11 reader.close(); 12 }
注:此讀取方式為一個字元的讀取,每讀取一個字元便寫到控制檯,以下程式碼演示高效的讀取,即宣告一個緩衝區的陣列,把每次所讀到的內容先放入緩衝陣列中去,然後再一次性寫到檔案中
1 public static void function_demo4() throws IOException { 2 //讀取流物件 3 FileReader reader = new FileReader("demo.txt"); 4 //每次讀取到的字元放入的緩衝陣列區 5 char[] buf = new char[1024]; 6 //每次讀取到的字元數 7 int i; 8 //迴圈讀取,每次read一次把讀取到的內容放入buf字元陣列,讀到最後會返回-1 9 while ((i = reader.read(buf)) != -1) { 10 //把讀取到的字元轉為字串,每次轉換的數量為讀取到的字元數 11 System.out.println(new String(buf, 0, i)); 12 } 13 reader.close(); 14 }
下面用兩種方式實現檔案的複製功能
private static void function_demo5() throws IOException { FileReader fr = new FileReader("demo.txt");//建立讀取流物件 FileWriter fw = new FileWriter("demo2.txt");//建立寫入流物件,若檔案不存在則建立;若存在則覆蓋 int ch;//儲存讀取到的字元 //迴圈讀取檔案中的資料 while ((ch = fr.read()) != -1) { fw.write(ch);//把每次讀到的內容寫入到新檔案中 } fw.close();//關閉 fr.close();//關閉 }
高效的複製方式
1 private static void function_demo6() throws IOException { 2 FileReader fr = new FileReader("demo.txt");// 建立讀取流物件 3 FileWriter fw = new FileWriter("demo3.txt");// 建立寫入流物件,若檔案不存在則建立,若存在則覆蓋 4 char[] buf = new char[4096];//快取陣列 5 int ch;// 儲存讀取到的字元 6 // 迴圈讀取檔案中的資料 7 while ((ch = fr.read(buf)) != -1) {//把每次讀取到的內容放入快取陣列中 8 fw.write(buf, 0, ch);//從快取陣列中把內容讀出來 9 } 10 fw.close();//關閉流 11 fr.close();//關閉流 12 }
五,高效的讀取流BufferedReader
從字元輸入流中讀取文字,緩衝各個字元,從而實現字元、陣列和行的高效讀取。注意,此類可以直接讀取行,由此也說明此類是專門為高效的讀取檔案資料的方式
1 private static void function_demo7() throws IOException { 2 FileReader fr = new FileReader("demo.txt");//讀取流物件 3 BufferedReader bReader = new BufferedReader(fr);//緩衝讀取流物件,需要傳入讀取Reader的實現類 4 int ch; 5 while ((ch = bReader.read()) != -1) {//此read為增強了的read方法,用的裝飾器模式 6 System.out.println((char) ch); 7 } 8 bReader.close();//關閉該流並釋放與之關聯的所有資源;即也把讀取流的物件fr給關閉了,不需要再手動呼叫fr.close() 9 }帶緩衝陣列的讀取方式
1 private static void function_demo7() throws IOException { 2 FileReader fr = new FileReader("demo.txt");// 讀取流物件 3 BufferedReader bReader = new BufferedReader(fr);// 緩衝讀取流物件,需要傳入讀取Reader的實現類 4 int ch = 0; 5 char[] buff = new char[1024]; 6 while ((ch = bReader.read(buff)) != -1) {// 此read為增強了的read方法,用的裝飾器模式 7 System.out.println(new String(buff, 0, ch)); 8 } 9 bReader.close();// 關閉該流並釋放與之關聯的所有資源;即也把讀取流的物件fr給關閉了,不需要再手動呼叫fr.close() 10 }讀取行
1 private static void function_demo8() throws IOException { 2 FileReader fr = new FileReader("demo.txt"); 3 BufferedReader bReader = new BufferedReader(fr); 4 String line = null;//獲取每次讀到的行內容 5 while ((line = bReader.readLine()) != null) {//如果讀取到了最後,則返回null 6 System.out.println(line); 7 } 8 bReader.close(); 9 }六, 高效的寫入流BufferedWriter 將文字寫入字元輸出流,緩衝各個字元,從而提供單個字元、陣列和字串的高效寫入。此流寫入的時候提供了一個newLine方法,可換行。
1 private static void function_demo9() throws IOException { 2 FileWriter fw = new FileWriter("demo4.txt"); 3 BufferedWriter bw = new BufferedWriter(fw); 4 bw.write("LioneTree"); 5 bw.newLine(); 6 bw.write("go kb go kb nnw huo kb "); 7 bw.close(); 8 }七,使用BufferedReader與BufferedWriter實現檔案複製的功能
1 private static void function_demo10() throws IOException { 2 FileReader fReader = new FileReader("demo.txt");//讀取流物件 3 BufferedReader bReader = new BufferedReader(fReader);//緩衝讀取流物件,傳入fReader讀取流物件 4 FileWriter fWriter = new FileWriter("demo5.txt");//寫入流物件 5 BufferedWriter bWriter = new BufferedWriter(fWriter);//緩衝寫入流物件,傳入bWriter寫入流物件 6 String line=null;//儲存每次讀取到的行內容 7 while((line=bReader.readLine())!=null) {//如果檔案內容讀完了則返回null 8 bWriter.write(line);//寫入讀取到的每行內容 9 bWriter.newLine();//每讀完一行則換行 10 } 11 bReader.close();//關閉讀取流物件 12 bWriter.close();//關閉寫入流物件 13 }八,跟蹤行號的緩衝字元輸入流LineNumberReader 此類定義了方法
setLineNumber(int)
和 getLineNumber()
,它們可分別用於設定和獲取當前行號;字繼承自BufferedReader類
1 private static void function_demo11() throws IOException { 2 FileReader fr = new FileReader("demo.txt");// 讀取流物件 3 LineNumberReader lnr = new LineNumberReader(fr);// 行號讀取流物件,需要傳入讀取流fr物件 4 String line = null;// 儲存讀取到的內容 5 lnr.setLineNumber(100);// 設定起始行號,若不設定預設從0開始,在讀取到的每一行的末尾處自增1 6 while ((line = lnr.readLine()) != null) {// 按行讀取 7 System.out.println(lnr.getLineNumber() + " " + line); 8 } 9 lnr.close(); 10 }