昨天做了一个Servlet实现文件上传的功能,之前没仔细研究过commons-fileupload-1.2.1.jar,就随意网上搜了下例子,草率写完了,测试成功,感觉不错没出什么问题,回来无意之间又看到一篇文章说,用commons-fileupload-1.2.1.jar实现上传文件一定要加上commons-io-1.3.2.jar,我就开始纳闷了,我明明没有加这个io包测试成功,他居然说必须加,感觉肯定是有问题的,经过今天一上午研究最后终于找出原因为什么有人说加有人说不加啦,预知详情,请不要走开,
1,先把我的servlet简单的写出来,还有个jsp,没什么内容就几个<input type="file" >,就不列出来了,不要忘了form里加上enctype="multipart/form-data",没这个貌似不可以的。
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
FileBiz biz = new FileBiz();
String uploadPath = getServletContext().getRealPath("/");//获取文件路径
biz.upload(request,uploadPath);
response.getWriter().println("上传成功");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doGet(request, response);
}
2,列下我第一次没有加commons-io-1.3.2.jar情况下测试成功的代码。
public class FileBiz {
public void upload(HttpServletRequest request,String uploadPath) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
File tmpDir = new File("d:\\temp"); //初始化上传文件的临时存放目录,必须是绝对路径
try {
if (ServletFileUpload.isMultipartContent(request)) {
DiskFileItemFactory factory = new DiskFileItemFactory();
//指定在内存中缓存数据大小,单位为byte,这里设为1Mb
factory.setSizeThreshold(1 * 1024 * 1024);
//设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录
factory.setRepository(tmpDir);
ServletFileUpload sfu = new ServletFileUpload(factory);
// 指定单个上传文件的最大尺寸,单位:字节,这里设为5Mb
sfu.setFileSizeMax(5 * 1024 * 1024);
//指定一次上传多个文件的总尺寸,单位:字节,这里设为10Mb
sfu.setSizeMax(10 * 1024 * 1024);
sfu.setHeaderEncoding("UTF-8"); //设置编码,因为我的jsp页面的编码是utf-8的
FileItemIterator fii = sfu.getItemIterator(request);// 解析request请求
uploadPath = uploadPath + "upload\\"; // 选定上传的目录此处为当前目录
if (!new File(uploadPath).isDirectory()){
new File(uploadPath).mkdirs(); //选定上传的目录此处为当前目录,没有则创建
}
int index = 0;
while (fii.hasNext()) {
FileItemStream fis = fii.next();// 从集合中获得一个文件流
if (!fis.isFormField() && fis.getName().length() > 0) {// 过滤掉表单中非文件域
String fileName = fis.getName().substring(
fis.getName().lastIndexOf("."));// 获得上传文件的文件名
fileName = sdf.format(new Date())+"-"+index+fileName;
BufferedInputStream in = new BufferedInputStream(fis.openStream());
BufferedOutputStream out = new BufferedOutputStream(
new FileOutputStream(new File(uploadPath + "\\" + fileName)));
Streams.copy(in, out, true); // 开始把文件写到你指定的上传文件夹
index++;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意这里的写入文件时调用是commons.fileupload.util.Streams工具类的静态方法。
以上就可以实现上传了,这个是支持多文件上传的。
3,我想既然有人说需要加commons-io包的,要么是环境跟我的不一样,要么是实现的方法跟我的不一样,我的环境是
windows +tomcat6.0+jdk1.5,环境不容易改变,只有改变方法啦。
改变后的load方法。
public void uploads(HttpServletRequest request,String uploadPath){
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
File tmpDir = new File("d:\\temp");
try {
if (ServletFileUpload.isMultipartContent(request)) {
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1 * 1024 * 1024);
factory.setRepository(tmpDir);
ServletFileUpload sfu = new ServletFileUpload(factory);
sfu.setFileSizeMax(5 * 1024 * 1024);
sfu.setSizeMax(10 * 1024 * 1024);
sfu.setHeaderEncoding("UTF-8");
List<FileItem> fileItems = sfu.parseRequest(request);
uploadPath = uploadPath + "upload\\";
if (!new File(uploadPath).isDirectory()){
new File(uploadPath).mkdirs();
}
int leng = fileItems.size();
for(int n=0;n<leng;n++) {
FileItem item = fileItems.get(n); // 从集合中获得一个文件流
// 如果是普通表单字段
if(item.isFormField()) {
String name = item.getFieldName(); // 获得该字段名称
String value = item.getString("utf-8"); //获得该字段值
System.out.println(name+value);
}else if(item.getName().length()>0) { // 如果为文件域
String iname = item.getName().substring(
item.getName().lastIndexOf("."));
String fname=sdf.format(new Date())+"-"+n+iname;
try {
item.write(new File(uploadPath, fname)); // 写入文件
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
一测试,不行啦,报错了,马上加上commons-io-1.3.2.jar,再测试,OK。
原来是实现方法不一样,说不需要加包的都是基于第一种方法实现的,说需要加的都是第二种。
必须知道为什么会这样,下载commons-fileupload-1.2.1.jar源代码看看,
找到第一种方法源代码如下
public static long copy(InputStream pIn,
OutputStream pOut, boolean pClose,
byte[] pBuffer)
throws IOException {
OutputStream out = pOut;
InputStream in = pIn;
try {
long total = 0;
for (;;) {
int res = in.read(pBuffer);
if (res == -1) {
break;
}
if (res > 0) {
total += res;
if (out != null) {
out.write(pBuffer, 0, res);
}
}
}
if (out != null) {
if (pClose) {
out.close();
} else {
out.flush();
}
out = null;
}
in.close();
in = null;
return total;
} finally {
if (in != null) {
try {
in.close();
} catch (Throwable t) {
/* Ignore me */
}
}
if (pClose && out != null) {
try {
out.close();
} catch (Throwable t) {
/* Ignore me */
}
}
}
}
第二种源代码如下,FileItem是个interface,要找DiskFileItem类,
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.DeferredFileOutputStream;
public class DiskFileItem
implements FileItem, FileItemHeadersSupport {
FileItem.write方法就是DiskFileItem.write方法,其中写文件时用的就是IOUitls类写的,
BufferedInputStream in = null;
BufferedOutputStream out = null;
try {
in = new BufferedInputStream(
new FileInputStream(outputFile));
out = new BufferedOutputStream(
new FileOutputStream(file));
IOUtils.copy(in, out);
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
//方法有点长,把主要挖出来
最后还测试了下性能问题,简单测试显示第二种方法比快很多,毕竟commons-io-1.3.2.jar是专业处理io的嘛,哈哈
这应该就是加不加commons-io-1.3.2.jar的原因了吧。。
分享到:
相关推荐
开发工具 commons-fileupload-1.3.2开发工具 commons-fileupload-1.3.2开发工具 commons-fileupload-1.3.2开发工具 commons-fileupload-1.3.2开发工具 commons-fileupload-1.3.2开发工具 commons-fileupload-1.3.2...
java+servlet+commons-io-2.4.jar+commons-fileupload-1.3.jar实现文件的上传与下载
commons-fileupload-1.3.3.jar和commons-io-2.6.jar最新版本
赠送jar包:commons-fileupload-1.4.jar; 赠送原API文档:commons-fileupload-1.4-javadoc.jar; 赠送源代码:commons-fileupload-1.4-sources.jar; 赠送Maven依赖信息文件:commons-fileupload-1.4.pom; 包含...
commons commons-fileupload历史版本jar包集合,包括src源码 附件列表: commons-fileupload-1.0.zip commons-fileupload-1.1.1.zip commons-fileupload-1.1.zip commons-fileupload-1.2.1-bin.zip commons-...
commons-fileupload-1.3.2jar包和commons-io-2.5jar包,可以到http://commons.apache.org里面下载最新版本。
commons-fileupload-1.3.2.jar和commons-io-2.5.jar
赠送jar包:commons-fileupload-1.3.3.jar; 赠送原API文档:commons-fileupload-1.3.3-javadoc.jar; 赠送源代码:commons-fileupload-1.3.3-sources.jar; 赠送Maven依赖信息文件:commons-fileupload-1.3.3.pom;...
commons-fileupload实现文件上传
java实现文件保存,接收所需的jar包,(commons-fileupload-1.2.1.jar,commons-io-2.0.1.jar),亲测可用
commons-fileupload实现文件上传下载
commons-fileupload-1.2.2commons-fileupload-1.2.2commons-fileupload-1.2.2commons-fileupload-1.2.2commons-fileupload-1.2.2commons-fileupload-1.2.2commons-fileupload-1.2.2commons-fileupload-1.2.2commons-...
用开源的FileUpload组件,可以很方便的给自己的系统添加功能强大的文件上传模块。 该资源文件是两个jar打包成的压缩文件。
commons-fileupload.rar;包括commons-fileupload-1.3.1-bin和commons-io-2.4两个文件;文件上传接口需要这个包;
commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar jar 文件。 commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar 案例上传: http://hi.baidu.com/lichao77821/blog commons-fileupload-1.2.1.jar和commons-...
文件上传两个jar包commons-fileupload-1.3.1和commons-io-2.4,也是现在用的最多的两个jar包。
使用commons-fileupload实现的文件上传和下载,上传和下载都没有中文乱码问题
commons-fileupload ,commons-io commons-fileupload ,commons-io commons-fileupload ,commons-io
commons-fileupload-1.3.2 commons-io-2.5 Servelet文件上传jar包
使用commons-fileupload上传文件 使用commons-fileupload上传文件