fastupload提供两种从multipart/form-data表单请求数据中解析文件的方法,直接法和批量法
直接法:
是fastupload提供的第一种解析方法,从HttpServletRequest的InputStream中每次读取不超过8K的数据到缓冲区之中,从这个缓冲区里解析是否有文件,或者是文件的一部分数据,把每次解析的结果“直接 ”保存到磁盘文件中去。fastupload最先实现的是这种方式,这种方式一个好处就是对内存的占用非常小,解析内容的缓冲只有8K。因此非常适合那种 对内存要求很苛刻的应用场景,而且解析的速度也非常快,这里有几组比较数据,可以参考一下,http://mojarra.iteye.com/blog /1581521, http://mojarra.iteye.com/blog/1579986
具体的API使用如下
DiskFileFactory dff = new DiskFileFactory(System.getProperty("user.home"));
DiskFileFactory dff = new DiskFileFactory(System.getProperty("user.home") , "utf-8");
DiskFileFactory dff = new DiskFileFactory(System.getProperty("user.home") , "utf-8", 0x20000);
dff.setParseThreshold(0x100000);
HttpFileUploadParser parser = new HttpFileUploadParser(req, dff);
List<MultiPartFile> files = parser.parse();
在解析文件之前,需要创建DiskFileFactory工厂,用来指定解析时用来的一些必要的“数据”,DiskFileFactory有三种构造函数,
第一种,创建DiskFileFactory工厂,文件保存在用户home目录下,使用jdk默认的文件编码,无文件大小限制
第二种,创建DiskFileFactory工厂,文件保存在用户home目录下,使用utf-8编码,无文件大小限制
第三种,创建DiskFileFactory工厂,文件保存在用户home目录下,使用utf-8编码,文件大小限制在0x20000
上面的列子中,第四行代码可以和这三个构造函数配合使用,来限制整个请求的数据的大小,如果指定 了整个请求数据的大小,即指定了ParseThreshold的值,类HttpFileUploadParser在解析文件之前,先和 HttpServletRequest的Content-Length相比较,如果发现ParseThreshold>Content- Length,直接抛出ThresholdException异常。
这里稍微提醒一下,因为HTTP协议的规定,HTTP请求的Content-Length会比上传文件的实际字节数稍微大一点。
上面代码的第五、六行,创建HttpFileUploadParser对象,并解析文件。如果指定了字符编码,解析过程中把文件名转换成所指定的字符编码,除此之外,若解析过程发现了文本文件,也会对文件的内容进行转码。
批量法:
fastupload提供的第二种解析方式,是把HttpServletRequest的 InputStream中所有的数据都读取到一片大的缓冲区中(相对于第一种方式种所采用的8K缓冲区,不知道要大多少倍的),再从这片大的缓冲区中,解 析multipart/form-data数据中的文件或者其他输入内容。解析出来的数据通过MultiPartData类中提供的一些API,让API 使用者可以对这些数据进行操作。
因为是把HttpServletRequest的InputStream中所有的数据读入缓冲后,做一次解析的,所以批量法解析的速度是非常快的,比第一种要快3倍以上,因此,批量法非常适合那种对速度相应要快,不太介意内存使用、高并发上传小文件的场合。
这里与直接法有些不同,批量法除了支持解析文件外,还支持解析multipart/form-data中非文件的上传数据,比如表单中的文本输入框中用户手工的输入数据。
MultiPartDataFactory mpdf = new MemoryMultiPartDataFactory();
MultiPartDataFactory mpdf = new MemoryMultiPartDataFactory("utf-8");
MultiPartDataFactory mpdf = new MemoryMultiPartDataFactory("utf-8", 0x20000);
mpdf.setParseThreshold(0x100000);
HttpMemoryUploadParser httpMemoryUploadParser = new HttpMemoryUploadParser(
request, mpdf);
List<MultiPartData> list = httpMemoryUploadParser.parseList();
for (MultiPartData e : list) {
String target = String.format("%s/%s", dir.getAbsolutePath(), e.getFileName());
if (e.isFile()) {
e.toFile(target);
} else {
if (e.getBytes() > 0)
System.out.println(new String(e.getContentBuffer()));
}
}
创建MemoryMultiPartDataFactory 与创建DiskFileFactory基本相同,只不过少了一个path参数,(确实,内存中的数据不需要path
),编码、文件大小限制,解析总长度与DiskFileFactory都起着一样的作用,这里不在复述。
经过httpMemoryUploadParser解析出的multipart/form- data表单中的各部分内容,都会保存在一个包含MultiPartData对象的数组之中,API使用者可以MultiPartData类封装的几个与 上传内容重点相关的函数来访问解析的内容。
MultiPartData.getBytes(),返回该MultiPartData对象中数据缓冲的字节数。如果是0,表示当前对象中不包含任何数据
[暂时写这么多,欢迎大家提意见,我会继续完善]
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
等提供了对struts2、spring mvc3的注解(annotation)一些高级特性的支持,而且不是SNAPSHOT版了时,在好好试试.^_^######对这些特性的支持,和这个表单文件上传的本身关系不大,不过能方便这些框架的使用者######您好,能给介绍少为啥会说他的效率在java实现中,比common-fileupload 要快吗?######fastupload采用了BM算法,查找的效率比commons fileupload的算法效率高,而commons fileupload采取的是类似于KMP查找######我使用过fileupload和cos,在实际应用中cos是要比fileupload快,当时cos很久不更新了,不知道这个如何。######我测试的样本是1.7M, 1.7M,1.2M的三个文件,得出的结论是给予这个测试的,不知道你测试的样本是什么样的,能否告诉我?######持续关注.######
对于第一种方式,因为少量buffer写入文件,所以和cos相比,fastupload略快,第二种方式,把所有数据读取到内存后再解析,比目前所有同类中的其他上传组件都要快很多。这里有一些测试数据,http://www.oschina.net/news/32272/fastupload-0-31,其中也fastupload快速的查找算法也有提到
很简单的servlet,也是从网上收集的
cos
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.oreilly.servlet.MultipartRequest;
public class CosUploadHandler extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/xml; charset=utf-8");
String rootPath = "D:\\";
PrintWriter out = response.getWriter();
String uploadDir = null;
// int fileNum = 0;
if(request.getParameter("folder") != null) {
uploadDir = request.getParameter("folder");
uploadDir = rootPath + uploadDir;
}
uploadDir = "D:\\upload";
// if(request.getParameter("fileNum")!= null) {
// fileNum = Integer.parseInt(request.getParameter("fileNum"));
// }
int maxPostSize = 200 * 1024 * 1024;
MultipartRequest multipartRequest = null;
try {
multipartRequest = new MultipartRequest(request,uploadDir,maxPostSize,"utf-8");
} catch(IOException ex) {
out.println("error!");
out.flush();
out.close();
return;
}
Enumeration<?> fileNames = multipartRequest.getFileNames();
while(fileNames.hasMoreElements()) {
String fileName = (String)fileNames.nextElement();
multipartRequest.getFile(fileName);
System.out.println(multipartRequest.getFilesystemName(fileName));
}
out.println("success!");
out.flush();
out.close();
}
}
fileupload
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class FileUploadHandler extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/xml; charset=utf-8");
// PrintWriter out = response.getWriter();
String uploadDir = null;
if(request.getParameter("uploadDir") != null) {
uploadDir = request.getParameter("uploadDir");
uploadDir = "D:\\" +uploadDir;
}
uploadDir = "D:\\upload";
if(!ServletFileUpload.isMultipartContent(request))
{
// out.println("只能处理 multipart/form-data 类型的数据!");
return;
}
DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
fileItemFactory.setSizeThreshold(1024*1024);
ServletFileUpload fileUpload = new ServletFileUpload(fileItemFactory);
fileUpload.setHeaderEncoding("utf-8");
fileUpload.setFileSizeMax(1024 * 1024 * 200);
List itemList = null;
Iterator iterator = null;
try {
itemList = fileUpload.parseRequest(request);
} catch (FileUploadException e) {
// out.println("解析数据时出现如下问题:");
// e.printStackTrace(out);
// e.printStackTrace();
return;
}
iterator = itemList.iterator();
while(iterator.hasNext()) {
FileItem fileItem = (FileItem)iterator.next();
if(!fileItem.isFormField()) {
String srcPath = fileItem.getName();
if(srcPath.trim().equals("")){
continue;
}
String fileName = srcPath.substring(srcPath.lastIndexOf("//") + 1);
File destFile = new File(uploadDir,fileName);
try {
fileItem.write(destFile);
} catch (Exception e) {
// out.println("存储文件时出现如下问题:");
// e.printStackTrace(out);
// e.printStackTrace();
fileItem.delete();
return;
}
fileItem.delete();
}
}
// out.flush();
// out.close();
}
}
######
DiskFileItemFactory不是fastupload中的类,fastupload的代码应该是这样的
DiskFileFactory dff = new DiskFileFactory(System.getProperty("user.home") , "utf-8");
dff.setParseThreshold(0x100000);
HttpFileUploadParser parser = new HttpFileUploadParser(req, dff);
List<MultiPartFile> files = parser.parse();