Java拷文件4种方法及效率实验


01、传统方式

参数分别是原始文件、目的文件。

分别对2个文件构建输入输出流,并且使用一个字节数组作为我们内存的缓存器
然后使用流从f1 中读出数据到缓存里,在将缓存数据写到f2里面去.这里的缓存是2MB的字节数组

public static long forJava(File f1,File f2) throws Exception
{
    long time=new Date().getTime();
    int length=2097152;
    FileInputStream in=new FileInputStream(f1);
    FileOutputStream out=new FileOutputStream(f2);
    byte[] buffer=new byte[length];

    while(true)
    {
        int ins=in.read(buffer);
        if(ins==-1)
        {
            in.close();
            out.flush();
            out.close();
            return new Date().getTime()-time;
        }
        else out.write(buffer,0,ins);
    }
}


02、使用NIO中的管道到管道传输

在第一种方法基础上对输入输出流获得其管道,然后分批次的从f1的管道中向f2的管道中输入数据,每次输入最大为2MB


public static long forTransfer(File f1,File f2) throws Exception
{
    long time=new Date().getTime();
    int length=2097152;
    FileInputStream in=new FileInputStream(f1);
    FileOutputStream out=new FileOutputStream(f2);
    FileChannel inC=in.getChannel();
    FileChannel outC=out.getChannel();
    int i=0;

    while(true)
    {
        if(inC.position()==inC.size())
        {
            inC.close();
            outC.close();
            return new Date().getTime()-time;
        }

        if((inC.size()-inC.position())<20971520) length=(int)(inC.size()-inC.position());
        else length=20971520;

        inC.transferTo(inC.position(),length,outC);
        inC.position(inC.position()+length);
        i++;
    }
}

03、内存文件镜像写

(读文件没有使用文件镜像,有兴趣的可以试试,我就不试了,估计会更快)

跟上两个例子不一样,这里写文件流没有使用管道而是使用内存文件映射(假设文件f2在内存中)。

在循环中从f1的管道中读取数据到字节数组里,然后在像内存映射的f2文件中写数据.


public static long forImage(File f1, File f2) throws Exception
{
    long time=new Date().getTime();
    int length=2097152;
    FileInputStream in=new FileInputStream(f1);
    RandomAccessFile out=new RandomAccessFile(f2,"rw");
    FileChannel inC=in.getChannel();
    MappedByteBuffer outC=null;
    MappedByteBuffer inbuffer=null;
    byte[] b=new byte[length];
    while(true)
    {
        if(inC.position()==inC.size())
        {
            inC.close();
            outC.force();
            out.close();
            return new Date().getTime()-time;
        }
        if((inC.size()-inC.position())<length)
        {
            length=(int)(inC.size()-inC.position());
        }
        else
        {
            length=20971520;
        }
        b=new byte[length];
        inbuffer=inC.map(MapMode.READ_ONLY,inC.position(),length);
        inbuffer.load();
        inbuffer.get(b);
        outC=out.getChannel().map(MapMode.READ_WRITE,inC.position(),length);
        inC.position(b.length+inC.position());
        outC.put(b);
        outC.force();
    }
}

04、管道对管道

这里实现方式与第3种实现方式很类似,不过没有使用内存映射.


public static long forChannel(File f1,File f2) throws Exception
{
    long time=new Date().getTime();
    int length=2097152;
    FileInputStream in=new FileInputStream(f1);
    FileOutputStream out=new FileOutputStream(f2);
    FileChannel inC=in.getChannel();
    FileChannel outC=out.getChannel();
    ByteBuffer b=null;
    while(true)
    {
        if(inC.position()==inC.size())
        {
            inC.close();
            outC.close();
            return new Date().getTime()-time;
        }
        if((inC.size()-inC.position())<length)
        {
            length=(int)(inC.size()-inC.position());
        }else
            length=2097152;
        b=ByteBuffer.allocateDirect(length);
        inC.read(b);
        b.flip();
        outC.write(b);
        outC.force(false);
    }
}

05、总结

下面是对49.3MB的文件进行拷贝的测试时间(毫秒)

Start Copy File...  file size:50290KB
CopyFile:b1.rmvb mode:forChannel  RunTime:3203
CopyFile:b1.rmvb mode:forImage  RunTime:3328
CopyFile:b1.rmvb mode:forJava  RunTime:2172
CopyFile:b1.rmvb mode:forTransfer RunTime:1406
End Copy File!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值