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

来源:互联网 发布:最全小说软件 编辑:程序博客网 时间:2024/06/05 04:49

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
原创粉丝点击