zoukankan      html  css  js  c++  java
  • 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。

  • 相关阅读:
    什么是蓝绿部署和滚动部署
    北漂--我的2018
    辛苦俩月总结的面试题,掌握它怼翻面试官不是梦~
    记一次项目谈判的失败经历,要拒绝免费开发!
    程序员技术入股的那些坑
    记一次程序员在办公室里的“撕逼”经历
    公司来了个“奇葩”的程序员
    苦逼程序员如何在公司生存的经验分享
    (第二部)程序员逆天改命之胜天半子
    别闹了,颠覆世界不是为了让它变得更糟
  • 原文地址:https://www.cnblogs.com/hamhog/p/3550158.html
Copyright © 2011-2022 走看看