FileInputStream 與 BufferedInputStream 效率對比


我的技術博客經常被流氓網站惡意爬取轉載。請移步原文:http://www.cnblogs.com/hamhog/p/3550158.html ,享受整齊的排版、有效的鏈接、正確的代碼縮進、更好的閱讀體驗。

【問題】

FileInputStream & FileOutputStream 和 BufferedInputStream & BufferedOutputStream 都能完成文件的讀寫。它們在原理上、時間效率上有什么不同,實際應用時應該如何選擇呢?

【實驗】

我們采用文件復制來做效率對比的實驗。

在FileOperator類的copyWithFileStream方法實現了使用FileInputStream和FileOutputStream復制文件,copyWithBufferedStream方法實現了使用BufferedInputStream和BufferedOutputStream復制文件。

/* * Copyright (c) 2014 xxx.com. All Rights Reserved. */

package utils; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * @author ham.hog created on 2014 14-2-12 下午2:58 * @version 0 */
public class FileOperator { /** buffer size in bytes */
    final static int BUFFER_SIZE = 100; /** * copy file using FileInputStream & FileOutputStream * @param src copy from * @param dest copy to * @return; */
    public static void copyWithFileStream(File src, File dest){ FileInputStream input = null; FileOutputStream output = null; try { input = new FileInputStream(src); output = new FileOutputStream(dest); byte[] buffer = new byte[BUFFER_SIZE]; int copySize; while ((copySize = input.read(buffer)) > 0){ output.write(buffer, 0, copySize); output.flush(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { input.close(); output.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * copy file using BufferedInputStream & BufferedOutputStream * @param src copy from file * @param dest copy to file * @return; */
    public static void copyWithBufferedStream(File src, File dest){ BufferedInputStream bufferedInput = null; BufferedOutputStream bufferedOutput = null; try { bufferedInput = new BufferedInputStream(new FileInputStream(src)); bufferedOutput = new BufferedOutputStream(new FileOutputStream(dest)); byte[] buffer = new byte[BUFFER_SIZE]; int copySize; while ((copySize = bufferedInput.read(buffer)) > 0){ bufferedOutput.write(buffer, 0, copySize); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { bufferedInput.close(); bufferedOutput.close(); } catch (IOException e) { e.printStackTrace(); } } } } class FileOperatorTest{ public static void main(String args[]){ File src = new File("test.txt"); File dest = new File("copyTest.txt"); try { if (!dest.exists()){ dest.createNewFile(); } } catch (IOException e) { e.printStackTrace(); } //test copy using FileStream
        int startTime = System.currentTimeMillis(); FileOperator.copyWithFileStream(src, dest); int endTime = System.currentTimeMillis(); System.out.println("Copy file using FileStream takes : " + (endTime - startTime) + " ms."); //test copy using BufferedStream
 startTime = System.currentTimeMillis(); FileOperator.copyWithBufferedStream(src, dest); endTime = System.currentTimeMillis(); System.out.println("Copy file using BufferedStream takes : " + (endTime - startTime) + " ms."); } }

【運行結果】
測試文件大小約為900M,以下是在設定BUFFER_SIZE為不同值時的一次執行結果:

BUFFER_SIZE = 100
Copy file using FileStream takes: 42680 ms.
Copy file using BufferedStream takes: 2407 ms.

BUFFER_SIZE = 8192
Copy file using FileStream takes: 1689 ms.
Copy file using BufferedStream takes: 1654 ms.

BUFFER_SIZE = 1000000
Copy file using FileStream takes: 957 ms.
Copy file using BufferedStream takes: 929 ms.

 

【對時間效率差異的解釋】
BufferedInputStream比FileInputStream多了一個緩沖區,執行read時先從緩沖區讀取,當緩沖區數據讀完時再把緩沖區填滿。
因此,當每次讀取的數據量很小時,FileInputStream每次都是從硬盤讀入,而BufferedInputStream大部分是從緩沖區讀入。讀取內存速度比讀取硬盤速度快得多,因此BufferedInputStream效率高。
BufferedInputStream的默認緩沖區大小是8192字節。當每次讀取數據量接近或遠超這個值時,兩者效率就沒有明顯差別了。
BufferedOutputStream和FileOutputStream同理,差異更明顯一些。

 

【結論】

一般情況下,我們應該優先選取BufferedInputStream&BufferedOutputStream。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM