测试FileInputStream和BufferedInputStream效率



FileInputStream和BufferedInputStream谁更快?FileInputStream 与 BufferedInputStream 效率比较。

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。