使用 java 进行文件拷贝 相信很多人都会用,,不过效率上是否最好呢?
最近看了看NIO决定试一试 java NIO 到底有什么性能的提升.
第一种方法:古老的方式
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中的管道到管道传输
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:内存文件景象写(读文件没有使用文件景象,有兴趣的可以回去试试,,我就不试了,估计会更快)
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种方法:管道对管道
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!
PS:这个一个上传方法 用的uploadify插件
public ReturnObject uploadFile(String deleteFileName,
HttpServletRequest request,HttpServletResponse response)
throws IOException{
System.out.println("附件上传sessionInfo:"
+ ContextUtils.getSession().getId());
String basePath = Global.BASE_UPLOAD_FOLDER; // 获取基础路径
String TemporaryFile=Global.BASE_UPLOAD_TEMPORARYFILE;//获取临时文件夹
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
Map<String,MultipartFile> fileMap = multipartRequest.getFileMap();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
SimpleDateFormat sp = new SimpleDateFormat("yyyyMMdd");
// TODO multi-tenant.id 目前租户ID都是707 待以后完善后multi-tenant.id 就是租户ID
String ctxPath = basePath + File.separator + 707 + File.separator
+ ContextUtils.getCurrentSecurityUser().getUsername()
+ File.separator+TemporaryFile+File.separator;// 完整路径
String ctxPathView = sp.format(new Date()) + "/";// 用于在数据库存储的路径-从文件夹开始
String ymd = sdf.format(new Date());
// 如果不存在,创建文件夹
File file = new File(ctxPath);
if (!file.exists()){
file.mkdirs();
}
ReturnObject ro = new ReturnObject();
String fileNames = "";
for (Map.Entry<String,MultipartFile> entity : fileMap.entrySet()){
MultipartFile mf = entity.getValue();
String fileFullname = mf.getOriginalFilename();
// String fileName = mf.getOriginalFilename();
String fileName = ymd + "_" + fileFullname;
File uploadFile = new File(ctxPath + fileName);
try{
FileCopyUtils.copy(mf.getBytes(),uploadFile); //可以利用此方法进行文件移动,通过流直接移动
// copy成功之后保存上传数据记录
UploadFile uploadBean = new UploadFile();
uploadBean.setUpdUser(ContextUtils.getCurrentSecurityUser()
.getUsername());
uploadBean.setOriginName(fileFullname);
uploadBean.setFileName(fileName);
uploadBean.setUpdTime(new Date());
uploadBean.setIsFunction("other");
if (uploadBean != null){
uploadFileService.save(uploadBean);
}
fileNames += fileName + ",";
}
catch (IOException e){
e.printStackTrace();
ro.setSuccess(false);
ro.setMsg(e.getMessage());
return ro;
}
}
if (fileNames.endsWith(",")){
fileNames = fileNames.substring(0,fileNames.length() - 1);
}
ro.setSuccess(true);
ro.setMsg("上传文件成功");
HashMap<String,Object> hsfiled = new HashMap<String,Object>();
hsfiled.put("fileNames",fileNames);
hsfiled.put("filepatch",ctxPathView);// 数据库保存路径(从时间开始截取的)
ro.setObj(hsfiled);
// 清空不需要的历史文件
try{
log.info("删除不需要的文件:" + deleteFileName);
String ctPath = basePath + File.separator + File.separator
+ deleteFileName;
// 如果不存在,创建文件夹
if (deleteFileName != null){
File fileTobeDelete = new File(ctPath);
if (fileTobeDelete.exists()){
fileTobeDelete.delete();
}
}
}
catch (Exception e){
log.error("删除历史文件出错:" + e.getMessage());
}
return ro;
}
相关推荐
### Java文件上传方法详解 在Java开发中,文件上传是一个非常常见的需求,尤其是在Web应用程序中。本文将基于提供的代码片段,详细介绍如何使用Java实现文件上传功能,并解释代码中的关键部分。 #### 一、代码结构...
java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件上传工具类java 文件...
java 文件上传工具类 java 文件上传工具类java 文件上传工具类 java 文件上传工具类java 文件上传工具类 java 文件上传工具类java 文件上传工具类 java 文件上传工具类java 文件上传工具类 java 文件上传工具类java ...
Java 文件上传程序 Java 文件上传程序是指使用 Java 语言编写的文件上传程序,负责接收和处理客户端上传的文件。以下是 Java 文件上传程序的相关知识点: 1. 服务器端编程:Java 文件上传程序的服务器端使用 Java ...
当文件上传请求到达服务器时,这些方法会接收文件流,保存到服务器的磁盘上,或者将其存储到数据库或云存储服务中。处理上传的Java代码需要考虑到文件大小限制、错误处理、文件命名规则以及安全性等方面的问题。 ...
"性能最好的Java文件上传组件"是指一种优化了上传速度和资源消耗的工具,它能够有效地处理大文件上传、多文件并发上传等问题,提高应用的用户体验。在这个场景中,我们提到了基于"COS"的Java文件上传组件。COS通常指...
在Java编程语言中,文件上传是一项常见的功能,广泛应用于各种Web应用中,如社交媒体平台、云存储服务等。实现基于Java的文件上传涉及到多个技术点,包括Servlet、HTTP协议、多部分请求(Multipart Request)以及...
利用java图形化界面和网络编程相结合实现的--文件上传。 运行步骤: (1)分别运行工程两个包中的两个.java文件(UploadClient.java和UploadServer.java)分别会弹出“上传客服端”和“上传服务器”两个窗口。 ...
Java 实现上传文件类型检测过程解析是指在进行文件上传时,对上传文件的格式进行控制,以防止黑客将病毒脚本上传。单纯的将文件名的类型进行截取的方式非常容易遭到破解,上传者只需要将病毒改换文件名便可以完成...
首先,我们来看“java文件上传”这个知识点。Java提供了多种方法来处理文件上传,最常见的是使用Servlet API中的Part接口,这是Java EE 7引入的,专门用于处理multipart/form-data类型的HTTP请求,也就是通常用于...
首先,我们需要理解Java中的文件上传机制。在Java Servlet规范中,`multipart/form-data`类型的HTTP请求用于处理文件上传。`javax.servlet.http.Part`接口提供了处理上传文件的方法。通常,我们使用Servlet 3.0及...
在Java开发中,文件上传和下载是常见的功能需求,尤其在网络应用中,如网页、桌面应用或移动应用。为了实现这些功能,开发者通常需要引入特定的库或jar包。在这个场景下,"文件上传下载需要的jar包"指的是用于处理...
在Java编程语言中,文件上传是一项常见的...总的来说,"java文件上传组件包"提供了一系列工具和方法,帮助开发者高效、安全地处理文件上传任务。通过理解并熟练运用这些知识点,你可以构建出稳定可靠的文件上传系统。
本示例("java文件上传dome")聚焦于使用Tomcat中的Servlet和Apache Commons FileUpload库来实现这一功能。以下是这个示例中涉及的关键知识点: 1. **Servlet**: Servlet是Java EE中用于扩展服务器功能的Java类。...
在Java开发中,多文件上传是一项常见的功能,尤其在Web应用中,用户可能需要一次性上传多个文件,如图片、文档等。本知识点将详细介绍如何在Java中实现这一功能,以及结合Flash实现上传界面并显示上传进度条。 1. *...
总的来说,这个源码包提供了从客户端文件选择、HTTP上传、服务器端接收、文件保存到服务器的完整流程,是学习和理解Java文件上传功能的好例子。通过深入研究和实践,开发者可以掌握文件上传这一核心的Web开发技能。
在Java Spring框架中,文件上传是一项常见的功能,用于接收用户通过Web界面提交的文件。Spring提供了强大的MultipartFile接口,使得处理文件上传变得简单且高效。本文将深入探讨如何使用Java和Spring实现文件上传,...
在Java编程中,文件上传是一项常见的任务,尤其在开发Web应用程序...通过这个简单的Java文件上传例子,开发者可以学习如何在实际项目中实现文件上传功能,并理解相关的技术细节。这有助于提升Web应用的交互性和功能性。
纯java代码,演示上传文件,适合任何文件,主要是了解HTTP请求的信息,然后解析请求的字符串,此事例只考虑了现在的两种主要的浏览器的请求,因为浏览器不一样文件名会有差异,IE就只有文件名,而FF就是全路径名
这两个库提供了强大的文件操作和文件上传功能,是Java开发者处理文件上传问题的得力助手。 首先,`commons-io-2.5.jar`是Apache Commons IO库的一部分,这是一个用于处理输入/输出操作的Java库。它提供了许多实用...