FileInputStream 与 BufferedInputStream 效率对比

 在FileOperator类的copyWithFileStream方法实现了使用FileInputStream和FileOutputStream复制文件,copyWithBufferedStream方法实现了使用BufferedInputStream和BufferedOutputStream复制文件。

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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是Java复制文件的四种方式,分别使用FileInputStreamBufferedInputStream类中的两种read()方法: 方式一:使用FileInputStreamread()方法逐字节复制文件 ```java import java.io.*; public class FileCopyDemo1 { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); FileInputStream fis = new FileInputStream("d:\\bbb.mp4"); FileOutputStream fos = new FileOutputStream("copy.mp4"); int b; while ((b = fis.read()) != -1) { fos.write(b); } fis.close(); fos.close(); long end = System.currentTimeMillis(); System.out.println("用时:" + (end - start) + "毫秒"); } } ``` 方式二:使用FileInputStreamBufferedInputStreamread()方法读取缓冲区,每次复制1024字节 ```java import java.io.*; public class FileCopyDemo2 { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); FileInputStream fis = new FileInputStream("d:\\bbb.mp4"); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("copy.mp4"); byte[] buffer = new byte[1024]; int len; while ((len = bis.read(buffer)) != -1) { fos.write(buffer, 0, len); } bis.close(); fis.close(); fos.close(); long end = System.currentTimeMillis(); System.out.println("用时:" + (end - start) + "毫秒"); } } ``` 方式三:使用FileInputStreamBufferedInputStreamread()方法读取缓冲区,每次复制8192字节 ```java import java.io.*; public class FileCopyDemo3 { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); FileInputStream fis = new FileInputStream("d:\\bbb.mp4"); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("copy.mp4"); byte[] buffer = new byte[8192]; int len; while ((len = bis.read(buffer)) != -1) { fos.write(buffer, 0, len); } bis.close(); fis.close(); fos.close(); long end = System.currentTimeMillis(); System.out.println("用时:" + (end - start) + "毫秒"); } } ``` 方式四:使用Files.copy()方法复制文件 ```java import java.io.*; import java.nio.file.*; public class FileCopyDemo4 { public static void main(String[] args) throws IOException { long start = System.currentTimeMillis(); Path source = Paths.get("d:\\bbb.mp4"); Path target = Paths.get("copy.mp4"); Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); long end = System.currentTimeMillis(); System.out.println("用时:" + (end - start) + "毫秒"); } } ``` 这里使用Java 8中的Files.copy()方法,可以一行代码完成文件复制操作。 经过测试,第一个方式复制文件最慢,第四个方式复制文件最快。第二和第三个方式的效率相差不大,但是第三个方式复制的字节数更多,因此第三个方式更高效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值