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

来源:互联网 发布:域名投资怎么理解 编辑:程序博客网 时间:2024/06/07 20:24

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

阅读全文
0 0