解决方案
方案名称:带进度条的大文件上传
方案时间:2012-08-16
编写人员:yummy
开发环境:windowsXP+jdk1.6(注:jdk1.5编译不稳定,有问题!)
方案资料:
解决这种大文件上传不太可能用web上传的方式,只有自己开发插件或是当门客户端上传,或者用现有的ftp等。
1)开发一个web插件。用于上传文件。
2)开发一个FTP工具,不用web上传。
3)用现有的FTP工具。
一般实现大文件上传的话肯定是不能使用HTTP协议的,因为这样会给服务器带来巨大的压力。使用HTTP协议上传一个500MB大小的文件,意味着要占用WEB服务器500MB的内存,如果同时有许多人上传这么大的文件,WEB服务器的内存会被撑爆。FTP的方式比HTTP的方式要更适合大文件的传输,而且借助于FTP协议可以轻松实现文件的断点续传。
网上针对这方面的技术支持很多,但是有的代码长度较为复杂,还有很多插件使用,好的插件都是要钱的,有的还比较贵,但是货真价实确实不错,这方面的测试资料(源码)也有,但是主要是做为测试用的,放在服务器上面就不能用了,真的说,插件还是比较好用些。
考虑到费用问题和其他需求问题,自己做了个简单的上传,然后网上加加工就搞定了,其实上传功能很简单,但是要主要其他辅助功能就比较麻烦了,所以别人的插件要钱就是这个原因,因为别人做的插件几近完美的。 还有保障,闲话不多说了,进入正题。
优点:
文件上传速度较快,较一般的上传速度快些,文件处理的内部核心技术的差距吧,主要是后台无debug的输出,js处理了上传的核心部分。
缺点:
目前还没断点续传的功能添加, 因为针对状态的捕捉较难把握,后面争取添加断点续传的功能,完善效果。
简单效果图:
项目展开结构图:
说明:
fileSabeServlet.java做拓展,传值。
FileUtil.java做上传的核心类。
Js主要运作上传时的文件进度条,进度条采用swf格式处理。
其核心技术实现了无debug内部处理。
页面和样式部分。
源码分析部分:
/**
* 功能描述:使用fileupload components 上传多个文件,以上加码过程可不采用
* 这个是上传的主要方案,支持的大文件上传
* @author yummy
*/
public static List
boolean isMultipart = ServletFileUpload.isMultipartContent(request);//获取请求
Listnew ArrayList//列表
if(!isMultipart){
return resultList;
}
String userfilepath = request.getRealPath("userfile");
System.out.println("文件存储位置:"+userfilepath);
DiskFileItemFactory factory = new DiskFileItemFactory();//缓存
factory.setSizeThreshold(2 * 1024 * 1024);// 2MB
factory.setRepository(new File(userfilepath));//缓存地址
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("utf-8");//字符编码
//upload.setHeaderEncoding("gbk");//字符编码
upload.setSizeMax(1024 * 1024 * 1024*1);// 1G,大小可以自己定义
try {
List
for (FileItem item : items) {
if (item.isFormField()) {
//普通表单
} else {
String fieldName = item.getFieldName();
String fileName = item.getName();
System.out.println("文件的原名字:"+fileName);
//如果文件域没有填写内容,或者填写的文件不存在
if (StringUtils.isBlank(fileName) || item.getSize() == 0) {
continue;
}
String date = "/" + getTime8() + "/";//当天上传的一级文件创建
System.out.println("date:"+date);
String extName = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
System.out.println("文件的类型:"+extName);
//String newfilename = getUUID() + "." + extName;//备用文件加码,此时不采用此方案
String newfilename =fileName;//直接获取上传文件名
System.out.println("新的文件名字:"+newfilename);
File uploadedFile = new File(userfilepath + date + newfilename);
if (!uploadedFile.exists()) {// 如果要写入的文件或目录不存在,那么试着创建要写入的目录,以便写入文件
uploadedFile.getParentFile().mkdirs();
}
item.write(uploadedFile);
Map tmpfile = new HashMap(); //获取上传的文件列表
tmpfile.put("fieldname", fieldName);
tmpfile.put("filename", fileName.substring(fileName.lastIndexOf(File.separator) + 1, fileName.length()));
tmpfile.put("extname", extName);
tmpfile.put("filepath", "/userfile"+ date + newfilename);
resultList.add(tmpfile);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally{
return resultList;
}
}