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// 建立字元寫入流物件,接收一個要寫入的檔案路徑物件,此檔案若不存在則新建立一個檔案,若已存在則覆蓋的檔案 3FileWriter fw = new FileWriter("demo1.txt"); 4fw.write("abcdefg");// 把內容寫入緩衝區 5fw.flush();// 從緩衝區把內容刷入檔案中 6fw.close();// 關閉流 7}
注:以上程式碼中fw.flush()是把內容從緩衝區刷入到檔案中去,但是fw.close()方法是先把內容從緩衝區刷入到檔案中去即先呼叫flush方法,所以fw.flush()可以不用
FileWrite在寫時的 換行與續寫
1// 獲取系統換行的符號 2private static final String LINE_SEPARATOR = System.getProperty("line.separator"); 3public static void function_demo2() throws IOException { 4FileWriter writer = new FileWriter("demo.txt", true);// 建立寫入流物件 5// 把內容寫入到緩衝區 6writer.write("abcdef綿" + LINE_SEPARATOR + "中國人啊吼叫職了"); 7// 把緩衝區裡的內容刷入到檔案系統中 8// writer.flush(); 9// 關閉流,在關閉之前會先把緩衝區裡的內容刷入到檔案系統然後才關閉流;若用此關閉流可不用手動呼叫flush 10writer.close(); 11}
注:FileWriter在支援續寫的時候提供了一個帶兩個引數的建構函式,當傳遞為true時即可支援續寫;換行可呼叫系統提供的換行符號
四,字元流 FileReader
1 public static void function_demo3() throws IOException { 2// 建立讀取流物件,指定需要讀取的檔案地址 3FileReader reader = new FileReader("demo.txt"); 4// 宣告一個變數接收讀取到的字元 5int ch; 6// 呼叫read方法讀取檔案中的字元,當讀取到檔案的末尾的時候read方法返回-1 7while ((ch = reader.read()) != -1) { 8System.out.println((char) ch); 9} 10// 關閉流 11reader.close(); 12}
注:此讀取方式為一個字元的讀取,每讀取一個字元便寫到控制檯,以下程式碼演示高效的讀取,即宣告一個緩衝區的陣列,把每次所讀到的內容先放入緩衝陣列中去,然後再一次性寫到檔案中
1public static void function_demo4() throws IOException { 2//讀取流物件 3FileReader reader = new FileReader("demo.txt"); 4//每次讀取到的字元放入的緩衝陣列區 5char[] buf = new char[1024]; 6//每次讀取到的字元數 7int i; 8//迴圈讀取,每次read一次把讀取到的內容放入buf字元陣列,讀到最後會返回-1 9while ((i = reader.read(buf)) != -1) { 10//把讀取到的字元轉為字串,每次轉換的數量為讀取到的字元數 11System.out.println(new String(buf, 0, i)); 12} 13reader.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();//關閉 }
高效的複製方式
1private static void function_demo6() throws IOException { 2FileReader fr = new FileReader("demo.txt");// 建立讀取流物件 3FileWriter fw = new FileWriter("demo3.txt");// 建立寫入流物件,若檔案不存在則建立,若存在則覆蓋 4char[] buf = new char[4096];//快取陣列 5int ch;// 儲存讀取到的字元 6// 迴圈讀取檔案中的資料 7while ((ch = fr.read(buf)) != -1) {//把每次讀取到的內容放入快取陣列中 8fw.write(buf, 0, ch);//從快取陣列中把內容讀出來 9} 10fw.close();//關閉流 11fr.close();//關閉流 12}
五,高效的讀取流 BufferedReader
從字元輸入流中讀取文字,緩衝各個字元,從而實現字元、陣列和行的高效讀取。注意,此類可以直接讀取行,由此也說明此類是專門為高效的讀取檔案資料的方式
1 private static void function_demo7() throws IOException { 2FileReader fr = new FileReader("demo.txt");//讀取流物件 3BufferedReader bReader = new BufferedReader(fr);//緩衝讀取流物件,需要傳入讀取Reader的實現類 4int ch; 5while ((ch = bReader.read()) != -1) {//此read為增強了的read方法,用的裝飾器模式 6System.out.println((char) ch); 7} 8bReader.close();//關閉該流並釋放與之關聯的所有資源;即也把讀取流的物件fr給關閉了,不需要再手動呼叫fr.close() 9}
1 private static void function_demo7() throws IOException { 2FileReader fr = new FileReader("demo.txt");// 讀取流物件 3BufferedReader bReader = new BufferedReader(fr);// 緩衝讀取流物件,需要傳入讀取Reader的實現類 4int ch = 0; 5char[] buff = new char[1024]; 6while ((ch = bReader.read(buff)) != -1) {// 此read為增強了的read方法,用的裝飾器模式 7System.out.println(new String(buff, 0, ch)); 8} 9bReader.close();// 關閉該流並釋放與之關聯的所有資源;即也把讀取流的物件fr給關閉了,不需要再手動呼叫fr.close() 10}
1 private static void function_demo8() throws IOException { 2FileReader fr = new FileReader("demo.txt"); 3BufferedReader bReader = new BufferedReader(fr); 4String line = null;//獲取每次讀到的行內容 5while ((line = bReader.readLine()) != null) {//如果讀取到了最後,則返回null 6System.out.println(line); 7} 8bReader.close(); 9}
六, 高效的寫入流 BufferedWriter
1 private static void function_demo9() throws IOException { 2FileWriter fw = new FileWriter("demo4.txt"); 3BufferedWriter bw = new BufferedWriter(fw); 4bw.write("LioneTree"); 5bw.newLine(); 6bw.write("go kb go kbnnw huo kb "); 7bw.close(); 8}
1 private static void function_demo10() throws IOException { 2FileReader fReader = new FileReader("demo.txt");//讀取流物件 3BufferedReader bReader = new BufferedReader(fReader);//緩衝讀取流物件,傳入fReader讀取流物件 4FileWriter fWriter = new FileWriter("demo5.txt");//寫入流物件 5BufferedWriter bWriter = new BufferedWriter(fWriter);//緩衝寫入流物件,傳入bWriter寫入流物件 6String line=null;//儲存每次讀取到的行內容 7while((line=bReader.readLine())!=null) {//如果檔案內容讀完了則返回null 8bWriter.write(line);//寫入讀取到的每行內容 9bWriter.newLine();//每讀完一行則換行 10} 11bReader.close();//關閉讀取流物件 12bWriter.close();//關閉寫入流物件 13}
八,跟蹤行號的緩衝字元輸入流 LineNumberReader
1 private static void function_demo11() throws IOException { 2FileReader fr = new FileReader("demo.txt");// 讀取流物件 3LineNumberReader lnr = new LineNumberReader(fr);// 行號讀取流物件,需要傳入讀取流fr物件 4String line = null;// 儲存讀取到的內容 5lnr.setLineNumber(100);// 設定起始行號,若不設定預設從0開始,在讀取到的每一行的末尾處自增1 6while ((line = lnr.readLine()) != null) {// 按行讀取 7System.out.println(lnr.getLineNumber() + "" + line); 8} 9lnr.close(); 10}