利用commons-fileupload 实现文件上传终极版及commons-fileupload和commons-io包关系

转载 2015年11月20日 23:09:14

昨天做了一个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",没这个貌似不可以的。

Java代码  收藏代码
  1. public void doGet(HttpServletRequest request, HttpServletResponse response)  
  2.         throws ServletException, IOException {  
  3.     response.setCharacterEncoding("UTF-8");  
  4.     FileBiz biz = new FileBiz();  
  5.     String uploadPath = getServletContext().getRealPath("/");//获取文件路径  
  6.     biz.upload(request,uploadPath);  
  7.     response.getWriter().println("上传成功");  
  8. }  
  9.   
  10. public void doPost(HttpServletRequest request, HttpServletResponse response)  
  11.         throws ServletException, IOException {  
  12.     this.doGet(request, response);  
  13. }  

 2,列下我第一次没有加commons-io-1.3.2.jar情况下测试成功的代码。

Java代码  收藏代码
  1. public class FileBiz {  
  2.       
  3.     public void upload(HttpServletRequest request,String uploadPath) {  
  4.         SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");  
  5.         File tmpDir = new File("d:\\temp"); //初始化上传文件的临时存放目录,必须是绝对路径  
  6.         try {  
  7.             if (ServletFileUpload.isMultipartContent(request)) {  
  8.                 DiskFileItemFactory factory = new DiskFileItemFactory();  
  9.                 //指定在内存中缓存数据大小,单位为byte,这里设为1Mb  
  10.                 factory.setSizeThreshold(1 * 1024 * 1024);   
  11.                 //设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录  
  12.                 factory.setRepository(tmpDir);   
  13.                 ServletFileUpload sfu = new ServletFileUpload(factory);  
  14.                  // 指定单个上传文件的最大尺寸,单位:字节,这里设为5Mb  
  15.                 sfu.setFileSizeMax(5 * 1024 * 1024);  
  16.                 //指定一次上传多个文件的总尺寸,单位:字节,这里设为10Mb  
  17.                 sfu.setSizeMax(10 * 1024 * 1024);   
  18.                 sfu.setHeaderEncoding("UTF-8"); //设置编码,因为我的jsp页面的编码是utf-8的  
  19.                 FileItemIterator fii = sfu.getItemIterator(request);// 解析request请求  
  20.                 uploadPath = uploadPath + "upload\\"// 选定上传的目录此处为当前目录  
  21.                 if (!new File(uploadPath).isDirectory()){  
  22.                     new File(uploadPath).mkdirs(); //选定上传的目录此处为当前目录,没有则创建  
  23.                 }  
  24.                   
  25.                 int index = 0;  
  26.                 while (fii.hasNext()) {  
  27.                     FileItemStream fis = fii.next();// 从集合中获得一个文件流  
  28.                     if (!fis.isFormField() && fis.getName().length() > 0) {// 过滤掉表单中非文件域  
  29.                         String fileName = fis.getName().substring(  
  30.                                 fis.getName().lastIndexOf("."));// 获得上传文件的文件名  
  31.                         fileName = sdf.format(new Date())+"-"+index+fileName;  
  32.                         BufferedInputStream in = new BufferedInputStream(fis.openStream());   
  33.                         BufferedOutputStream out = new BufferedOutputStream(  
  34.                                 new FileOutputStream(new File(uploadPath + "\\" + fileName)));  
  35.                         Streams.copy(in, out, true); // 开始把文件写到你指定的上传文件夹  
  36.                         index++;  
  37.                     }  
  38.                 }  
  39.   
  40.             }  
  41.         } catch (Exception e) {  
  42.             e.printStackTrace();  
  43.         }  
  44.     }  
  45. }  

 注意这里的写入文件时调用是commons.fileupload.util.Streams工具类的静态方法。

 以上就可以实现上传了,这个是支持多文件上传的。

 

 3,我想既然有人说需要加commons-io包的,要么是环境跟我的不一样,要么是实现的方法跟我的不一样,我的环境是

windows +tomcat6.0+jdk1.5,环境不容易改变,只有改变方法啦。

  改变后的load方法。

Java代码  收藏代码
  1. public void uploads(HttpServletRequest request,String uploadPath){  
  2.         SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");  
  3.         File tmpDir = new File("d:\\temp");   
  4.         try {  
  5.             if (ServletFileUpload.isMultipartContent(request)) {  
  6.                 DiskFileItemFactory factory = new DiskFileItemFactory();  
  7.                 factory.setSizeThreshold(1 * 1024 * 1024);   
  8.                 factory.setRepository(tmpDir);   
  9.                 ServletFileUpload sfu = new ServletFileUpload(factory);  
  10.                 sfu.setFileSizeMax(5 * 1024 * 1024);   
  11.                 sfu.setSizeMax(10 * 1024 * 1024);   
  12.                 sfu.setHeaderEncoding("UTF-8");  
  13.                 List<FileItem> fileItems = sfu.parseRequest(request);   
  14.                 uploadPath = uploadPath + "upload\\";  
  15.                 if (!new File(uploadPath).isDirectory()){  
  16.                     new File(uploadPath).mkdirs();   
  17.                 }  
  18.                 int leng = fileItems.size();  
  19.                 for(int n=0;n<leng;n++) {  
  20.                     FileItem item = fileItems.get(n); // 从集合中获得一个文件流  
  21.                     // 如果是普通表单字段    
  22.                     if(item.isFormField()) {    
  23.                         String name = item.getFieldName();  // 获得该字段名称  
  24.                         String value = item.getString("utf-8"); //获得该字段值  
  25.                         System.out.println(name+value);  
  26.                     }else if(item.getName().length()>0) { // 如果为文件域    
  27.                         String iname = item.getName().substring(  
  28.                                 item.getName().lastIndexOf("."));    
  29.                         String fname=sdf.format(new Date())+"-"+n+iname;  
  30.                           
  31.                         try {    
  32.                             item.write(new File(uploadPath, fname));  // 写入文件  
  33.                         } catch (Exception e) {    
  34.                             e.printStackTrace();    
  35.                         }  
  36.                     }  
  37.                 }  
  38.             }  
  39.         }catch (Exception e) {  
  40.             e.printStackTrace();  
  41.         }  
  42.     }  

 一测试,不行啦,报错了,马上加上commons-io-1.3.2.jar,再测试,OK。

原来是实现方法不一样,说不需要加包的都是基于第一种方法实现的,说需要加的都是第二种。

 

必须知道为什么会这样,下载commons-fileupload-1.2.1.jar源代码看看,

找到第一种方法源代码如下

Java代码  收藏代码
  1. public static long copy(InputStream pIn,  
  2.            OutputStream pOut, boolean pClose,  
  3.            byte[] pBuffer)  
  4.    throws IOException {  
  5.        OutputStream out = pOut;  
  6.        InputStream in = pIn;  
  7.        try {  
  8.            long total = 0;  
  9.            for (;;) {  
  10.                int res = in.read(pBuffer);  
  11.                if (res == -1) {  
  12.                    break;  
  13.                }  
  14.                if (res > 0) {  
  15.                    total += res;  
  16.                    if (out != null) {  
  17.                        out.write(pBuffer, 0, res);  
  18.                    }  
  19.                }  
  20.            }  
  21.            if (out != null) {  
  22.                if (pClose) {  
  23.                    out.close();  
  24.                } else {  
  25.                    out.flush();  
  26.                }  
  27.                out = null;  
  28.            }  
  29.            in.close();  
  30.            in = null;  
  31.            return total;  
  32.        } finally {  
  33.            if (in != null) {  
  34.                try {  
  35.                    in.close();  
  36.                } catch (Throwable t) {  
  37.                    /* Ignore me */  
  38.                }  
  39.            }  
  40.            if (pClose  &&  out != null) {  
  41.                try {  
  42.                    out.close();  
  43.                } catch (Throwable t) {  
  44.                    /* Ignore me */  
  45.                }  
  46.            }  
  47.        }  
  48.    }  

 第二种源代码如下,FileItem是个interface,要找DiskFileItem类,

Java代码  收藏代码
  1. import org.apache.commons.io.IOUtils;  
  2. import org.apache.commons.io.output.DeferredFileOutputStream;  
  3. public class DiskFileItem  
  4.     implements FileItem, FileItemHeadersSupport {  

 FileItem.write方法就是DiskFileItem.write方法,其中写文件时用的就是IOUitls类写的,

 

Java代码  收藏代码
  1.  BufferedInputStream in = null;  
  2.                     BufferedOutputStream out = null;  
  3.                     try {  
  4.                         in = new BufferedInputStream(  
  5.                             new FileInputStream(outputFile));  
  6.                         out = new BufferedOutputStream(  
  7.                                 new FileOutputStream(file));  
  8.                         IOUtils.copy(in, out);  
  9.                     } finally {  
  10.                         if (in != null) {  
  11.                                 in.close();  
  12.                         }  
  13.                         if (out != null) {  
  14.                                 out.close();  
  15.                         }  
  16.                     }  
  17. //方法有点长,把主要挖出来  

 最后还测试了下性能问题,简单测试显示第二种方法比快很多,毕竟commons-io-1.3.2.jar是专业处理io的嘛,哈哈

 

 这应该就是加不加commons-io-1.3.2.jar的原因了吧。。

相关文章推荐

利用 Commons-Fileupload 实现文件上传

文章转自:http://www.blogjava.net/kiant/articles/232301.html 一、准备: 1、 下载 commons-fileupload 库,下载地址:...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

java文件上传(使用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 写页面,写出一个form 提交 写一个servlet实...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

文件上传(使用commons-fileupload.jar以及commons-io.jar这两个jar文件)

(1)普通的实现方式: ①有ServletFileUpload获得是否是Multipart形式提交,如果是,执行② ②创建一个ServletFileUpload对象upload。 ③由上面的up...

使用commons-fileupload碰到的权限问题

最近在使用文件上传功能,使用的是apache的commons-fileupload控件,本地测试时,window上能正确使用,部署在linux上也能正确使用,但部署到线上环境时,能进入图片上传的方法,...

检查Mac电脑是32位还是64位运行以及修改方法

以前遇到过一种情况,就是开发的Mac PC端的App在客户Mac 10.7系统之下有问题。经过检查,发现我们提供的驱动是64位系统下运行的,但是客户的电脑是32位,结果导致通过kextload命令加载...

利用commons-fileupload 实现文件上传终极版及commons-fileupload和commons-io包关系

昨天做了一个Servlet实现文件上传的功能,之前没仔细研究过commons-fileupload-1.2.1.jar,就随意网上搜了下例子,草率写完了,测试成功,感觉不错没出什么问题,回来无意之间又...

利用apache的Commons-fileupload和Ajax实现文件上传进度条

实现思路: 1、
  • b671900
  • b671900
  • 2014年09月29日 17:19
  • 1869
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用commons-fileupload 实现文件上传终极版及commons-fileupload和commons-io包关系
举报原因:
原因补充:

(最多只允许输入30个字)