BufferedInputStream & BufferedOutputStream
如上面所介紹的那樣,在BufferedInputStream的構造函數中需要傳入一個InputStream, BufferedInputStream內部有一個字節數組緩沖區,每次執行read操作的時候就從這buf中讀取數據,從buf中讀取數據沒有多大的開銷。如果buf中已經沒有了要讀取的數據,那么就去執行其內部綁定的InputStream的read方法,而且是一次性讀取很大一塊數據,以便填充滿buf緩沖區。緩沖區buf的默認大小是8192字節,也就是8K,在構造函數中我們也可以自己傳入一個size指定緩沖區的大小。由於我們在執行BufferedInputStream的read操作的時候,很多時候都是從緩沖區中讀取的數據,這樣就大大減少了實際執行其指定的InputStream的read操作的次數,也就提高了讀取的效率。與BufferedInputStream 相對的是BufferedOutputStream。在BufferedOutputStream的構造函數中我們需要傳入一個OutputStream,這樣就將BufferedOutputStream與該OutputStream綁定在了一起。BufferedOutputStream內部有一個字節緩沖區buf,在執行write操作時,將要寫入的數據先一起緩存在一起,將其存入字節緩沖區buf中,buf是有限定大小的,默認的大小是8192字節,即8KB,當然也可以在構造函數中傳入size指定buf的大小。該buf只要被指定了大小之后就不會自動擴容,所以其是有限定大小的,既然有限定大小,就會有被填充完的時刻,當buf被填充完畢的時候會調用BufferedOutputStream的flushBuffer方法,該方法會通過調用其綁定的OutputStream的write方法將buf中的數據進行實際的寫入操作並將buf的指向歸零(可以看做是將buf中的數據清空)。如果想讓緩存區buf中的數據理解真的被寫入OutputStream中,可以調用flush方法,flush方法內部會調用flushBuffer方法。由於buf的存在,會大大減少實際執行OutputStream的write操作的次數,優化了寫的效率。
以下是BufferedInputStream 和 BufferedOutputStream的示例代碼片段:
private static void testBufferedInputOutputStream(){ try{ String inputFileName = "D:\\iWork\\file1.txt"; String outputFileName = "D:\\iWork\\file2.txt"; FileInputStream fis = new FileInputStream(inputFileName); BufferedInputStream bis = new BufferedInputStream(fis, 1024 * 10); FileOutputStream fos = new FileOutputStream(outputFileName); BufferedOutputStream bos = new BufferedOutputStream(fos, 1024 * 10); byte[] buf = new byte[1024]; int length = 0; while ((length = bis.read(buf)) > 0){ bos.write(buf, 0, length); } bis.close(); bos.close(); }catch (FileNotFoundException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } }
- 上面的代碼將從file1.txt讀取文件輸入流,然后將讀到的數據寫入到file2.txt中,即實現了將file1.txt拷貝到file2.txt中。其實不通過BufferedInputStream 和 BufferedOutputStream也可以完成這樣的工作,使用這個兩個類的好處是,可以對file1.txt的讀取以及file2.txt的寫入提高效率,從而提升文件拷貝的效率。