注:FileReader繼承InputStreamReader類,InputStreamReader實現Reader接口,其餘同理。windows
對於文件內容的操做主要分爲兩大類數組
分別是:框架
字符流函數
字節流測試
其中,字符流有兩個抽象類:Writer Reader優化
其對應子類FileWriter和FileReader可實現文件的讀寫操做編碼
BufferedWriter和BufferedReader可以提供緩衝區功能,用以提升效率spa
一樣,字節流也有兩個抽象類:InputStream OutputStream指針
其對應子類有FileInputStream和FileOutputStream實現文件讀寫code
BufferedInputStream和BufferedOutputStream提供緩衝區功能
字符流和字節流的主要區別:
1.字節流讀取的時候,讀到一個字節就返回一個字節; 字符流使用了字節流讀到一個或多個字節(中文對應的字節數是兩個,在UTF-8碼錶中是3個字節)時。先去查指定的編碼表,將查到的字符返回。
2.字節流能夠處理全部類型數據,如:圖片,MP3,AVI視頻文件,而字符流只能處理字符數據。只要是處理純文本數據,就要優先考慮使用字符流,除此以外都用字節流。
注意:
讀寫流使用完都要用.close方法關閉,防止佔用資源,可是在關閉以前防止空值最好作空值判斷再關閉;進行寫操做時想當即生效用write.flush()刷新。
注意寫文件路徑時盤符後面用\\或者/,如:c:\\demo.txt或者c:/demo.txt
BufferedReader特有方法:readLine(),將行標記以前的數據做爲字符串返回,讀到結尾時返回null,讀取行是將讀取的字符臨時存儲產生的效果。
具體操做方法以下:
FileReader(字符流的讀取)
FileReader 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)); } */ FileWriter(字符流的寫入) String path="E:\\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(); } } } 即FileWriter w = new FileWriter(path);//指定寫的路徑 w.write("Nerxious is a good boy\r\n");//寫入具體內容 文本文件的複製 String doc=」...」; String copy=」...」: FileReader r= new FileReader(doc); FileWriter 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)); } */ 利用字符流的緩衝區來進行文本文件的複製 FileReader r = new FileReader(doc); FileWriter w = new FileWriter(copy); //建立緩衝區對象 //將須要提升效率的FileReader和FileWriter對象放入其構造函數內 //固然,也可使用匿名對象的方式 br = new BufferedReader(new FileReader(doc)); BufferedReader br = new BufferedReader(r); BufferedWriter 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(); } 字節流: FileOutputStream(字符流的寫入) FileOutputStream o = new FileOutputStream(path); String str = "Nerxious is a good boy\r\n"; byte[] buf = str.getBytes(); //也能夠直接使用o.write("String".getBytes()); //由於字符串就是一個對象,能直接調用方法 o.write(buf); FileInputStream(字節流的讀取) FileInputStream i = new FileInputStream(path); //方式一:單個字符讀取 //須要注意的是,此處我用英文文本測試效果良好 //但中文就悲劇了,不過下面兩個方法效果良好 int ch = 0; while((ch=i.read()) != -1){ System.out.print((char)ch); } //方式二:數組循環讀取 /* byte[] buf = new byte[1024]; int len = 0; while((len = i.read(buf)) != -1) { System.out.println(new String(buf,0,len)); } */ //方式三:標準大小的數組讀取 /* //定一個一個恰好大小的數組 //available()方法返回文件的字節數 //可是,若是文件過大,內存溢出,那就悲劇了 //因此,親們要慎用!!!上面那個方法就不錯 byte[] buf = new byte[i.available()]; i.read(buf); //由於數組大小恰好,因此轉換爲字符串時無需在構造函數中設置起始點 System.out.println(new String(buf)); */ 二進制文件(即非純文本文件)的複製 Bin/copy爲 文件路徑,「E:\\demo.mp3」,此處示例文件爲mp3文件 FileInputStream i = null; FileOutputStream o = null; try { i = new FileInputStream(bin); o = new FileOutputStream(copy); //循環的方式讀入寫出文件,從而完成複製 byte[] buf = new byte[1024]; int temp = 0; while((temp = i.read(buf)) != -1) { o.write(buf, 0, temp); } 利用字節流的緩衝區進行二進制文件的複製 FileInputStream i = null; FileOutputStream o = null; BufferedInputStream bi = null; BufferedOutputStream bo = null; try { i = new FileInputStream(bin); o = new FileOutputStream(copy); bi = new BufferedInputStream(i); bo = new BufferedOutputStream(o); byte[] buf = new byte[1024]; int temp = 0; while((temp = bi.read(buf)) != -1) { bo.write(buf,0,temp); } 文件的操做 遞歸列出目錄下全部文件 File f = new File(path); //方式一:list() //返回一個包含指定目錄下全部文件名的字符串數組 //若是不是一個目錄則返回null String[] files = f.list(); for (String x : files) { System.out.println(x); } //方式二: if(f.isDirectory()){ File[] files = f.listFiles(); for(File x : files) { print(x); } } 二者都是返回目錄下的全部文件名,可是第二種方式更實用,爲遞歸列出文件作鋪墊 列出根目錄: //listRoots()是一個靜態方法,返回文件數組 File[] files = File.listRoots(); //foreach循環打印File對象 for (File x : files) { System.out.println(x); } 本地環境是Linux,因此根目錄只有一個 /,若是是Windows就能列出你的全部盤符 Scanner類: 從鍵盤讀取 Scanner input = new Scanner(System.in); System.out.println("請輸出一個整數:"); int i = input.nextInt(); System.out.println("你輸入的整數是:" + i); 從字符串讀取 Scanner input = new Scanner("hello\r\nworld\r\n"); //循環讀取,hasNext()方法和集合框架裏面的同樣使 while(input.hasNext()) { //每次讀取一行,別的讀取方法見API,比較簡單 String s = input.nextLine(); System.out.println(s); } 從文件讀取: File f = new File(path); //從文件構造Scanner對象,有可能產生異常 Scanner input = new Scanner(f); while(input.hasNext()) { String s = input.nextLine(); System.out.println(s); } PrintWriter類 向文件寫入內容 File file = new File(path); //此處構造函數還能夠傳其餘對象,具體參考API文檔 PrintWriter p = new PrintWriter(file); //向文件寫入一行,此外還有print()和printf()方法 p.println("若是有一天我回到從前"); p.println("回到最原始的我"); p.println("你是否會以爲我不錯"); //刷新流 p.flush(); 與PrintWriter相似的還有一個PrintStream類,此處以PrintWriter舉例是由於文本文件具備人爲可讀性,而二進制文件(字節模式)則須要使用專門的程序來讀取.可能有人會問:FileOutputStream、 FileWriter都能寫文件,那麼爲什麼還須要PrintWriter和PrintStream類,若是細看API文檔,能夠知道前者單純的字符寫入流和字節寫入流操做的方式大多用數組進行,對文件的細化處理很是不方便,而PrintWriter和PrintStream則很好的解決了這一問題,提供print()等方法,而且,PrintWriter和PrintStream對於不存在文件對象的狀況下會直接建立,若是已有文件對象,它們則會把原有文件給覆蓋掉,卻沒有增長方法。解決這問題也很簡單,再看API文檔,PrintWriter有一個構造方法PrintWriter(Writer out),也就是可以傳入Writer對象,PrintStream有一個構造方法PrintStream(OutputStream out),也就是能傳入OutputStream對象。所以,咱們這樣寫就能夠了 new PrintWriter(new FileWriter(file,true)) new PrintStream(new FileOutputStream(file,true)) 既能增長數據,也能更高效的處理文件,見以下代碼示範 File file = new File(path); //利用FileWriter方式構建PrintWriter對象,實現追加 PrintWriter p = new PrintWriter(new FileWriter(file,true)); p.println("尼瑪 這一句就是追加的 看到沒"); p.flush(); System類相關: //別忘了,OutputStream是全部字節寫入流的父類 OutputStream out = System.out; //寫入數據,只能是數組,因此用getBytes()方法 out.write("Hello,bitch!\r\n".getBytes()); System類中的讀取 InputStream in = System.in; System.out.print("請輸入文字: "); byte[] buf = new byte[1024]; int len = 0; //將輸入的數據保證到數組中,len記錄輸入的長度 len = in.read(buf); //用字符串的方式打印數組中的數據 System.out.println("你的輸入是: " + new String(buf,0,len)); 利用BufferedReader實現對鍵盤的讀取 BufferedReader b = new BufferedReader(new InputStreamReader(System.in)); System.out.print("請輸入文本:"); String str = b.readLine(); System.out.println("你輸入的是:" + str); //循環讀取方式 /* while(true) { System.out.print("請輸入文本:"); String str = b.readLine(); //若是輸入over就結束循環 if("over".equals(str)) { break; } System.out.println("你輸入的是:" + str);