Java实现文件拷贝的4种方法.
原文地址:http://blog.csdn.net/ta8210/article/details/2073817
使用 java 进行文件拷贝 相信很多人都会用,,不过效率上是否最好呢?
最近看了看NIO决定试一试 java NIO 到底有什么性能的提升.
第一种方法:古老的方式
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);
}
}
方法的2参数分别是原始文件,和拷贝的目的文件.这里不做过多介绍.
实现方法很简单,分别对2个文件构建输入输出流,并且使用一个字节数组作为我们内存的缓存器, 然后使用流从f1 中读出数据到缓存里,在将缓存数据写到f2里面去.这里的缓存是2MB的字节数组
第2种方法:使用NIO中的管道到管道传输
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++;
}
}
实现方法:在第一种实现方法基础上对输入输出流获得其管道,然后分批次的从f1的管道中像f2的管道中输入数据每次输入的数据最大为2MB
方法3:内存文件景象写(读文件没有使用文件景象,有兴趣的可以回去试试,,我就不试了,估计会更快)
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();
}
}
实现方法:跟伤2个例子不一样,这里写文件流没有使用管道而是使用内存文件映射(假设文件f2在内存中).在循环中从f1的管道中读取数据到字节数组里,然后在像内存映射的f2文件中写数据.
第4种方法:管道对管道
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);
}
}
这里实现方式与第3种实现方式很类似,不过没有使用内存影射.
下面是对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!
解释: 在测试结果中看到 古老方式,和管道向管道传输是最快的,,,,,为什么呢?
我分析是这样的,由于另外2种方法内部都使用了 字节数组作为缓存中转,在加上NIO内部有一个贴近系统的缓存区,这无意就增加了另一个缓存器,所以相对于这2个方法就要慢许多,,如果不使用 字节数组作为数据中转的话相信速度会更快的..
不过比较惊讶的是 管道向管道传输的速度还是真挺吓人,,,
我的机器是 IDE硬盘120G 硬盘缓存2MB, 内存1GB, CPU AMD2800+
Java实现文件拷贝的4种方法.的更多相关文章
- 总结java创建文件夹的4种方法及其优缺点-JAVA IO基础总结第三篇
本文是Java IO总结系列篇的第3篇,前篇的访问地址如下: 总结java中创建并写文件的5种方式-JAVA IO基础总结第一篇 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇 ...
- Java获取文件Content-Type的四种方法
HTTP Content-Type在线工具 有时候我们需要获取本地文件的Content-Type,已知 Jdk 自带了三种方式来获取文件类型. 另外还有第三方包 Magic 也提供了API.Magic ...
- Delphi中实现文件拷贝的三种方法
1.调用API函数procedure CopyFile(FromFileName,ToFileName:string);varf1,f2:file;BeginAssignFile(f1,FromFil ...
- 关于Java获取文件路径的几种方法
第一种:File f = new File(this.getClass().getResource("/").getPath()); System.out.println(f); ...
- Java获取文件路径的几种方法
第一种: File f = new File(this.getClass().getResource("/").getPath()); System.out.println(f); ...
- Java追加文件内容的三种方法
import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io. ...
- Java遍历文件夹的两种方法(非递归和递归)
import java.io.File; import java.util.LinkedList; public class FileSystem { public static int num ...
- 总结java中文件拷贝剪切的5种方式-JAVA IO基础总结第五篇
本文是Java IO总结系列篇的第5篇,前篇的访问地址如下: 总结java中创建并写文件的5种方式-JAVA IO基础总结第一篇 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇 ...
- 总结删除文件或文件夹的7种方法-JAVA IO基础总结第4篇
本文是Java IO总结系列篇的第4篇,前篇的访问地址如下: 总结java中创建并写文件的5种方式-JAVA IO基础总结第一篇 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇 ...
随机推荐
- 编程思想—依赖注入(DI)并非实现控制反转(IOC)的最佳方法
以构造函数注入为例: public class TestClass(IClassA a,IClassB b, IClassC C,IClassD d) { public void Method1() ...
- Mac os下安装pycurl
今天在Mac OS 10.9.2下安装pycurl时候失败,出现以下问题 Using curl-config (libcurl 7.30.0) clang: error: unknown argume ...
- iOS版 hello,world版本2
// // main.m // Hello // // Created by lishujun on 14-8-28. // Copyright (c) 2014年 lishujun. All rig ...
- IbatisNet开发使用小结
一. 介绍 平常做企业级应用,需求变化是经常的事,而很多基础代码重复也是很让人头疼的问题.所以很多人会使用一些ORM框架来增强项目的可维护性.可扩展性.IBatis.Net就是一个比较易用的ORM ...
- [BZOJ 3489] A simple rmq problem 【可持久化树套树】
题目链接:BZOJ - 3489 题目分析 “因为是OJ上的题,就简单点好了.”——出题人 真的..好..简单... 首先,我们求出每个数的前一个与它相同的数的位置,即 prev[i] ,如果前面没有 ...
- input text的outline属性
普通的text选中编辑时会出现蓝色的边框,感觉不太美观,怎么去掉呢? 可以在text对应的样式里加入:outline: 0;
- Delphi 类成员的默认访问权限(用RTTI检测)
类的成员,如果没有private.public等显示什么,直接在class下面,没有写访问权限的限定符,这种成员是不是默认的访问权限啊?还是publish的访问权限啊? --------------- ...
- Delphi 记事本 TMemo(5篇)
模仿的很不错,在本质上与windows记事本使用了同一个Edit. http://www.cnblogs.com/xe2011/category/524758.htmlhttp://www.cnblo ...
- ANDROID 中UID与PID的作用与区别
PID:为Process Identifier, PID就是各进程的身份标识,程序一运行系统就会自动分配给进程一个独一无二的PID.进程中止后PID被系统回收,可能会被继续分配给新运行的程序,但是在a ...
- 深入浅出Node.js (附录B) - 调试Node
B.1 Debugger B.2 Node Inspector B.2.1 安装Node Inspector B.2.2 错误堆栈