java IO流的继承关系如下
InputStream
|_FileInputStream
|_BufferedInputStream
BufferedInputStream 是套在其他InputStream之外的,是用来优化里面的InputStream的性能的,FileInputStream是读文件的实现,所以通常使用BufferedInputStream&BufferedOutputStream作为FileInputStream&FileOutputStream的外包装来优化读写的性能。
下面连个例子是个人实测:
package com.myapple.utils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOUtil_x {
/**
* 文件拷贝,不使用缓冲,一个字节一个字节读写
* @param oldFile
* @param newFile
* @throws IOException
*/
public static void copyFileByByte(File oldFile,File newFile)throws IOException{
if(!oldFile.exists()){
throw new IllegalArgumentException("文件:"+oldFile+"不存在.");
}
if(!oldFile.isFile()){
throw new IllegalArgumentException(oldFile+"不存在.");
}
FileInputStream in = new FileInputStream(oldFile);
FileOutputStream out = new FileOutputStream(newFile);
int c;
while((c=in.read())!=-1){
out.write(c);
out.flush();//刷新缓冲
}
in.close();
out.close();
}
/**
* 文件拷贝,使用字节数组,批量读取字节
* @param oldFile
* @param newFile
* @throws IOException
*/
public static void copyFileByByte_x(File oldFile,File newFile)throws IOException{
if(!oldFile.exists()){
throw new IllegalArgumentException("文件:"+oldFile+"不存在.");
}
if(!oldFile.isFile()){
throw new IllegalArgumentException(oldFile+"不是文件.");
}
FileInputStream in = new FileInputStream(oldFile);
FileOutputStream out = new FileOutputStream(newFile);
byte[] bytes = new byte[8*1024];//字节数组8k大小
int c;
while((c=in.read(bytes,0,bytes.length))!=-1){
out.write(bytes, 0, c);
out.flush();//刷新缓冲
}
in.close();
out.close();
}
/**
* 文件拷贝,使用缓冲,一个字节一个字节读写
* @param oldFile
* @param newFile
* @throws IOException
*/
public static void copyFileByBuffer(File oldFile,File newFile)throws IOException{
if(!oldFile.exists()){
throw new IllegalArgumentException("文件:"+oldFile+"不存在.");
}
if(!oldFile.isFile()){
throw new IllegalArgumentException(oldFile+"不是文件.");
}
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(oldFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile));
int c;
while((c=bis.read())!=-1){
bos.write(c);
bos.flush();//刷新缓冲
}
bis.close();
bos.close();
}
/**
* 文件拷贝,使用缓冲,批量读取字节
* 这是标准的IO,实际场景使用最多
* @param oldFile
* @param newFile
* @throws IOException
*/
public static void copyFileByBuffer_x(File oldFile,File newFile)throws IOException{
if(!oldFile.exists()){
throw new IllegalArgumentException("文件:"+oldFile+"不存在.");
}
if(!oldFile.isFile()){
throw new IllegalArgumentException(oldFile+"不是文件.");
}
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(oldFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile));
byte[] bytes = new byte[8*1024];//字节数组8k大小
int c;
while((c=bis.read(bytes,0,bytes.length))!=-1){
bos.write(bytes,0,c);
bos.flush();//刷新缓冲
}
bis.close();
bos.close();
}
}
package com.myapple.test;
import java.io.File;
import java.io.IOException;
import com.myapple.utils.IOUtil_x;
public class IOUtil_xTest {
public static void main(String[] args) {
File oldFile = new File("D:\\Eclipse\\workspaces\\mars2\\Myapple\\demo\\1.kgtemp");
try {
long start = System.currentTimeMillis();
//文件大小:3.18 MB (3,343,152 字节) 花费时间:199037毫秒
// IOUtil_x.copyFileByByte(oldFile, new File("D:\\Eclipse\\workspaces\\mars2\\Myapple\\demo\\a.kgtemp"));
//文件大小:3.18 MB (3,343,152 字节) 花费时间:59毫秒
//字节数组由8*1024修改为100 花费时间:2117毫秒 修改为100*1024 花费时间:23毫秒
IOUtil_x.copyFileByByte_x(oldFile, new File("D:\\Eclipse\\workspaces\\mars2\\Myapple\\demo\\b.kgtemp"));
//文件大小:3.18 MB (3,343,152 字节) 花费时间:169485毫秒
// IOUtil_x.copyFileByBuffer(oldFile, new File("D:\\Eclipse\\workspaces\\mars2\\Myapple\\demo\\c.kgtemp"));
//文件大小:3.18 MB (3,343,152 字节) 花费时间:61毫秒
//字节数组由8*1024修改为100 花费时间:1839毫秒 修改为100*1024 花费时间:31毫秒
// IOUtil_x.copyFileByBuffer_x(oldFile, new File("D:\\Eclipse\\workspaces\\mars2\\Myapple\\demo\\d.kgtemp"));
long end = System.currentTimeMillis();
System.out.println("拷贝文件话费了:" + (end - start) + "毫秒");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
经过测试:BufferedInputStream&BufferedOutputStream在不使用字节数组时性能明显高于FileInputStream&FileOutputStream,
使用字节数组做缓冲时,当BufferedInputStream&BufferedOutputStream设置的缓冲值小于8192时,性能明显优于FileInputStream&FileOutputStream,
越是接近8192两者的性能越是接近,当大于8192时,值越大反而性能比之FileInputStream&FileOutputStream差,不过相差不大。
应该时由于BufferedInputStream&BufferedOutputStream源码设计时默认缓冲区大小是8192字节导致,至于更深入的分析性能差异还望高手指点。
总结:一般情况下使用BufferedInputStream&BufferedOutputStream优化提高读写性能。