所謂IO,也就是Input與Output的縮寫。在java中,IO涉及的範圍比較大,這裏主要討論針對文件內容的讀寫
其他知識點將放置後續章節(我想,文章太長了,誰都沒耐心翻到最後)
對於文件內容的操作主要分爲兩大類
分別是:
字符流
字節流
其中,字符流有兩個抽象類:Writer ,Reader
其對應子類FileWriter和FileReader可實現文件的讀寫操作
BufferedWriter和BufferedReader能夠提供緩衝區功能,用以提高效率
同樣,字節流也有兩個抽象類:InputStream OutputStream
其對應子類有FileInputStream和FileOutputStream實現文件讀寫
BufferedInputStream和BufferedOutputStream提供緩衝區功能
俺當初學IO的時候犯了不少迷糊,網上有些代碼也無法通過編譯,甚至風格都很大不同,所以新手請注意:
1.本文代碼較長,不該省略的都沒省略,主要是因爲作爲一個新手需要養成良好的代碼編寫習慣
2.本文在linux下編譯,類似於File.pathSeparator和File.separator這種表示方法是出於跨平臺性和健壯性考慮
3.代碼中有些操作有多種執行方式,我採用了方式1...方式2...的表述,只需輕輕解開註釋便可編譯
4.代碼中並沒有在主方法上拋出異常,而是分別捕捉,造成代碼過長,如果僅是測試,或者不想有好的編程習慣,那你就隨便拋吧……
5.功能類似的地方就沒有重複寫註釋了,如果新手看不懂下面的代碼,那肯定是上面的沒有理解清楚
字符流
實例1:字符流的寫入
import java.io.File; import java.io.FileWriter; import java.io.IOException; public class Demo { public static void main(String[] args ) { //創建要操作的文件路徑和名稱 //其中,File.separator表示系統相關的分隔符,Linux下爲:/ Windows下爲:\\ String path = File.separator + "home" + File.separator + "siu" + File.separator + "work" + File.separator + "demo.txt"; //由於IO操作會拋出異常,因此在try語句塊的外部定義FileWriter的引用 FileWriter w = null; try { //以path爲路徑創建一個新的FileWriter對象 //如果需要追加數據,而不是覆蓋,則使用FileWriter(path,true)構造方法 w = new FileWriter(path); //將字符串寫入到流中,\r\n表示換行想有好的 w.write("Nerxious is a good boy\r\n"); //如果想馬上看到寫入效果,則需要調用w.flush()方法 w.flush(); } catch (IOException e) { e.printStackTrace(); } finally { //如果前面發生異常,那麼是無法產生w對象的 //因此要做出判斷,以免發生空指針異常 if(w != null) { try { //關閉流資源,需要再次捕捉異常 w.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
編譯之後,在目錄下面生成文件,並寫入字符串
實例2:字符流的讀取
import java.io.File; import java.io.FileReader; import java.io.IOException; public class Demo2 { public static void main(String[] args ) { String path = File.separator + "home" + File.separator + "siu" + File.separator + "work" + File.separator + "demo.txt"; FileReader r = null; try { r = new FileReader(path); //方式一:讀取單個字符的方式 //每讀取一次,向下移動一個字符單位 int temp1 = r.read(); System.out.println((char)temp1); int temp2 = r.read(); System.out.println((char)temp2); //方式二:循環讀取 //read()方法讀到文件末尾會返回-1 /* while (true) { int temp = r.read(); if (temp == -1) { break; } System.out.print((char)temp); } */ //方式三:循環讀取的簡化操作 //單個字符讀取,當temp不等於-1的時候打印字符 /*int temp = 0; while ((temp = r.read()) != -1) { System.out.print((char)temp); } */ //方式四:讀入到字符數組 /* char[] buf = new char[1024]; int temp = r.read(buf); //將數組轉化爲字符串打印,後面參數的意思是 //如果字符數組未滿,轉化成字符串打印後尾部也許會出現其他字符 //因此,讀取的字符有多少個,就轉化多少爲字符串 System.out.println(new String(buf,0,temp)); */ //方式五:讀入到字符數組的優化 //由於有時候文件太大,無法確定需要定義的數組大小 //因此一般定義數組長度爲1024,採用循環的方式讀入 /* char[] buf = new char[1024]; int temp = 0; while((temp = r.read(buf)) != -1) { System.out.print(new String(buf,0,temp)); } */ } catch (IOException e) { e.printStackTrace(); } finally { if(r != null) { try { r.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
編譯之後的效果:
實例3:文本文件的複製
import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo { public static void main(String[] args ) { String doc = File.separator + "home" + File.separator + "siu" + File.separator + "work" + File.separator + "demo.txt"; String copy = File.separator + "home" + File.separator + "siu" + File.separator + "life" + File.separator + "lrc.txt"; FileReader r = null; FileWriter w = null; try { r = new FileReader(doc); w = new FileWriter(copy); //方式一:單個字符寫入 int temp = 0; while((temp = r.read()) != -1) { w.write(temp); } //方式二:字符數組方式寫入 /* char[] buf = new char[1024]; int temp = 0; while ((temp = r.read(buf)) != -1) { w.write(new String(buf,0,temp)); } */ } catch (IOException e) { e.printStackTrace(); } finally { //分別判斷是否空指針引用,然後關閉流 if(r != null) { try { r.close(); } catch (IOException e) { e.printStackTrace(); } } if(w != null) { try { w.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
實例4:利用字符流的緩衝區來進行文本文件的複製
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class Demo { public static void main(String[] args ) { String doc = File.separator + "home" + File.separator + "siu" + File.separator + "work" + File.separator + "demo.txt"; String copy = File.separator + "home" + File.separator + "siu" + File.separator + "life" + File.separator + "lrc.txt"; FileReader r = null; FileWriter w = null; //創建緩衝區的引用 BufferedReader br = null; BufferedWriter bw = null; try { r = new FileReader(doc); w = new FileWriter(copy); //創建緩衝區對象 //將需要提高效率的FileReader和FileWriter對象放入其構造函數內 //當然,也可以使用匿名對象的方式 br = new BufferedReader(new FileReader(doc)); br = new BufferedReader(r); bw = new BufferedWriter(w); String line = null; //讀取行,直到返回null //readLine()方法只返回換行符之前的數據 while((line = br.readLine()) != null) { //使用BufferWriter對象的寫入方法 bw.write(line); //寫完文件內容之後換行 //newLine()方法依據平臺而定 //windows下的換行是\r\n //Linux下則是\n bw.newLine(); } } catch (IOException e) { e.printStackTrace(); } finally { //此處不再需要捕捉FileReader和FileWriter對象的異常 //關閉緩衝區就是關閉緩衝區中的流對象 if(br != null) { try { r.close(); } catch (IOException e) { e.printStackTrace(); } } if(bw != null) { try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } } }