java文件读写效率测试总结

文件读写效率总结
文件的读主要考虑:FileInputStream和BufferedInputStream两种输入流,对应的输出流是FileOutputStream和BufferedOutputStream两种输出流。
常规认为BufferedInputStream/BufferedOutputStream是处理流,自带大小为8192(8K)字节的缓冲区,效率会比FileInputStream/FileOutputStream的效率高。但是这种简单的比较是错误的,需要制定一定条件进行比较。下面就两种方式在不同情况下效率比较做一个总结。其中还有未解决的问题,希望大神给出解答。
fin->FileInputStream,fo->FileOutputStream;bfin->BufferedInputStream,bfo->BufferedOutputStream
(1)单字节处理,不指定缓冲区
while(fin.available() > 0) { //不指定缓冲区遍历输入
fo.write(fin.read());}
----------------------------------------
while(bfin.available() > 0) { //不指定缓冲区遍历输入
bfo.write(bfin.read());}
文件复制速度:fin(0.26M/s),bfin(0.7M/s),文件2G以内
========================================================
while((temp = fin.read()) != -1) { //不指定缓冲区,不遍历输入
fo.write(temp);}
----------------------------------------
while((temp = bfin.read()) != -1) { //不指定缓冲区,不遍历输入
bfo.write(temp);}
文件复制速度:fin(0.47M/s),bfin(18M/s)文件2G以内
=======================================================
(2)多字节处理,指定缓冲区
byte[] b = new byte[1]; //缓冲区为1个字节
while((fin.read(b)) != -1) {
fo.write(b);}
----------------------------------------------
while((bfin.read(b)) != -1) {
bfo.write(b);
文件复制速度:fin(0.47M/s),bfin(18M/s)文件2G以内
=========================================================
byte[] b = new byte[10];//缓冲区为10个字节
文件复制速度:fin(4.7M/s),bfin(135M/s)文件2G以内
======================================================
byte[] b = new byte[100];//缓冲区为100个字节
文件复制速度:fin(13.3M/s),bfin(315M/s)文件2G以内
======================================================
byte[] b = new byte[1024];//缓冲区为1024个字节
文件复制速度:fin文件2G以内(255M/s),文件2G以外(110M/s),bfin文件2G以内(750M/s),文件2G以外(110M/s)
=========================================================================================
byte[] b = new byte[8192];//缓冲区为8192个字节
文件复制速度:fin文件2G以内(830M/s),文件2G以外(110M/s),bfin文件2G以内(830M/s),文件2G以外(110M/s)
=========================================================================================
byte[] b = new byte[8192*10];//缓冲区为8192*10个字节
文件复制速度:fin文件2G以内(1365M/s),文件2G以外(110M/s),bfin文件2G以内(1365M/s),文件2G以外(110M/s)
=========================================================================================
byte[] b = new byte[8192*100];//缓冲区为8192*100个字节
文件复制速度:fin文件2G以内(1137M/s),文件2G以外(110M/s),bfin文件2G以内(1137M/s),文件2G以外(110M/s)
速度开始下降
=========================================================================================
byte[] b = new byte[8192*1000];//缓冲区为8192*1000个字节
文件复制速度:fin文件2G以内(751M/s),文件2G以外(110M/s),bfin文件2G以内(751M/s),文件2G以外(110M/s)
速度继续下降
===========================================================================================
总结:以指定缓存配合BufferedInputStream(其实缓存区超过8192字节时FileInputStream的速度也就一样了),选择合适长度字节。注意当指定的缓存区域过大或者待复制文件不能被缓存区整除是,复制的文件会造成扩大。


测试代码:
package day16;

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;
import java.nio.channels.FileChannel;

/**
* @author LPJ
* @version 1.0 创建时间:2018年1月1日 下午5:30:01
* describe:读取一个mp3文件,把此文件写入到new.mp3文件中,考虑到文件效率问题
*/
public class HW2_Copy {

public static void main(String[] args) {
FileInputStream fin,fin2;
BufferedInputStream bfin;
FileOutputStream fo,fo2;
BufferedOutputStream bfo;
try {
//--------------------------------------
File file = new File("d:/data/b.zip");
file.getName();
fin = new FileInputStream(file);
fo = new FileOutputStream("d:/data/b_1.zip");
int times = 0;
int count = 1;
int temp;
// while(fin.available() > 0) {//不指定缓冲区遍历输入
// fo.write(fin.read());
// while((temp = fin.read()) != -1) {//不指定缓冲区,不遍历输入
// fo.write(temp);
byte[] b = new byte[8192*1024];//缓冲区为1个字节
long d1 = System.currentTimeMillis();
// while((fin.read(b)) != -1) {
// fo.write(b);
// }
long d2 = System.currentTimeMillis();
System.out.println("复制完成,合计用时:" + (d2 - d1) / 1000.0 + "s");
//-----------------------------------------------------
File file2 = new File("d:/data/a.zip");
fin2 = new FileInputStream(file2);
bfin = new BufferedInputStream(fin2);
fo2 = new FileOutputStream("d:/data/a_1.zip");
bfo = new BufferedOutputStream(fo2);
times = 0;
count = 1;
long d3 = System.currentTimeMillis();
// while(bfin.available() > 0) {//不指定缓冲区
// bfo.write(bfin.read());
// while((temp = bfin.read()) != -1) {//不指定缓冲区,不遍历输入
// bfo.write(temp);
while((bfin.read(b)) != -1) {
bfo.write(b);
}
long d4 = System.currentTimeMillis();
System.out.println("buffer复制完成,合计用时:" + (d4 - d3) / 1000.0 + "s");
// ----方案1,速度高效286M 15S,不受内存大小限制速度18M/s
// while((tmp = bfin.read()) != -1) {
// bfo.write(tmp);
// ----方案2,速度慢,100M 150S,速度0.6M/s
// while(bfin.available() > 0) {
// bfo.write(bfin.read());
// -----方案3,与方案2速度一致
// while(bfin.available() > 0) {
// tmp = bfin.read();
// bfo.write(tmp);
// bfo.flush();严重影响速度
// ---方案4,速度最快
// 固定数值复制8912,10G数据1M43S,速度99M/s
// 固定数值复制8912 * 1024,10G数据a1M28S,速度116M/s
// 固定数值复制8912 * 8912,10G数据1M37S,速度105M/s
// 固定数值复制1024,10G数据1M47S,速度96M/s
// 固定数值复制10,10G数据2M32S,速度67M/s
// 固定数值复制1,10G数据10M6S,速度17M/s
// while((bfin.read(b)) != -1) {
// bfo.write(b);
try {
// in.close();
// out.close();
fo.close();
bfo.flush();
fin.close();
bfo.close();
bfin.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

你可能感兴趣的:(javaSE)