文件輸出流FileOutputStream跟FileWriter一樣有個毛病,每次調用write方法都會直接寫到磁盤,使得頻繁的寫操做性能極其低下。正如FileWriter搭上了緩存兄弟BufferedWriter那樣,FileOutputStream也有本身的緩存兄弟BufferedOutputStream,這個緩存輸出流的用法與緩存寫入器很是類似,主要體如今以下三點:
一、每次建立緩存輸出流對象以前,都要先構建文件輸出流對象,而後據此構建緩存輸出流對象;
二、它的write方法先把數據寫到緩存,等到緩存滿了才寫入磁盤,或者在調用close方法關閉文件之時將緩存數據寫入磁盤。
三、緩存輸出流仍然提供了flush方法,調用flush方法表示當即把緩存中的數據寫入磁盤。
下面是利用緩存輸出流寫文件的代碼例子:html
private static String mSrcName = "D:/test/aaf.txt"; // 利用緩存輸出流寫入文件 private static void writeBuffer() { String str = "白日依山盡,黃河入海流。\n欲窮千里目,更上一層樓。"; // 根據指定文件路徑構建文件輸出流對象,而後據此構建緩存輸出流對象 try (FileOutputStream fos = new FileOutputStream(mSrcName); BufferedOutputStream bos = new BufferedOutputStream(fos)) { bos.write(str.getBytes()); // 把字節數組寫入緩存輸出流 //bos.flush(); // 當即寫入磁盤。若是不當即寫入,最後調用close方法時也會寫入 } catch (Exception e) { e.printStackTrace(); } }
看過了緩存輸出流,再來看緩存輸入流BufferedInputStream。因爲字節流操做的數據形式爲字節數組,所以無論是緩存輸出流仍是緩存輸出流,都不提供按行讀寫的功能。若想建立緩存輸入流對象,依舊要先構建文件輸入流對象,再據此構建緩存輸入流對象。另外BufferedInputStream保留了mark和reset兩個方法,前者用於在當前位置作個標記,後者可重置輸入流指針,令其回到上次標記的位置。下面是利用緩存輸入流讀文件的代碼例子:數組
// 利用緩存輸入流讀取文件 private static void readBuffer() { // 根據指定文件路徑構建文件輸入流對象,而後據此構建緩存輸入流對象 try (FileInputStream fis = new FileInputStream(mSrcName); BufferedInputStream bis = new BufferedInputStream(fis)) { // 分配長度爲文件大小的字節數組。available方法返回當前位置後面的剩餘部分大小 byte[] bytes = new byte[bis.available()]; bis.read(bytes); // 從緩存輸入流中讀取字節數組 // 緩存輸入流的mark和reset用法相似於BufferedReader的同名方法 //bis.mark(bis.available()); // 在當前位置作個標記 //bis.reset(); // 重置輸入流指針,令其回到上次標記的位置 String content = new String(bytes); // 把字節數組轉換爲字符串 System.out.println("content="+content); } catch (Exception e) { e.printStackTrace(); } }
由於字節流只處理字節數組,不處理字符數組,因此藉助於字節數組能夠很輕鬆地在輸入和輸出流之間轉換。調用緩存輸入流對象的read方法,將文件數據讀到指定的字節數組;而後調用緩存輸出流對象的write方法,立刻把剛讀取的字節數組寫入文件,一進一出之間就順帶完成了文件複製功能。下面是經過緩存輸入和輸出流複製文件的代碼例子:緩存
private static String mSrcName = "D:/test/aaf.txt"; private static String mDestName = "D:/test/aaf_copy.txt"; // 利用緩存輸入和輸出流複製文件 private static void copyFile() { // 分別構建緩存輸入流對象和緩存輸出流對象 try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(mSrcName)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(mDestName))) { // 分配長度爲文件大小的字節數組。available方法返回當前位置後面的剩餘部分大小 byte[] bytes = new byte[bis.available()]; bis.read(bytes); // 從緩存輸入流中讀取字節數組 bos.write(bytes); // 把字節數組寫入緩存輸出流 System.out.println("文件複製完成,源文件大小="+bytes.length+",新文件大小="+bytes.length); } catch (Exception e) { e.printStackTrace(); } }
同以前介紹的經過緩存讀取器和寫入器複製文件相比,緩存輸入和輸出流在複製文件的時候去掉了惱人的循環語句,整個實現代碼顯得更加精練和高效。性能
更多Java技術文章參見《Java開發筆記(序)章節目錄》指針