FileInputStream&FileOutputStream 和 BufferedInputStream&BufferedOutputStrem的性能测试小案例

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优化提高读写性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值