java文件上传fileupload

本文介绍使用commons-fileupload进行文件上传的两种方法,一种是基于Streams工具类的静态方法,另一种是利用DiskFileItem的write方法。文章详细展示了每种方法的具体实现,并解释了是否需要依赖commons-io包的原因。

commons-fileupload-1.2.1.jar与commons-io-1.3.2.jar

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. public void doPost(HttpServletRequest request, HttpServletResponse response)
  10. throws ServletException, IOException {
  11. this.doGet(request, response);
  12. }
[java]  view plain copy
  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. public void doPost(HttpServletRequest request, HttpServletResponse response)
  10. throws ServletException, IOException {
  11. this.doGet(request, response);
  12. }

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

[java]  view plain copy
  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. try {
  31. item.write(new File(uploadPath, fname)); // 写入文件
  32. catch (Exception e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. }
  37. }
  38. }catch (Exception e) {
  39. e.printStackTrace();
  40. }
  41. }
[java]  view plain copy
  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. try {
  31. item.write(new File(uploadPath, fname)); // 写入文件
  32. catch (Exception e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. }
  37. }
  38. }catch (Exception e) {
  39. e.printStackTrace();
  40. }
  41. }

[java]  view plain copy
  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. }
[java]  view plain copy
  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. }

[java]  view plain copy
  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 {
[java]  view plain copy
  1. import org.apache.commons.io.IOUtils;
  2. import org.apache.commons.io.output.DeferredFileOutputStream;
  3. public class DiskFileItem
  4. implements FileItem, FileItemHeadersSupport {

[java]  view plain copy
  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. //方法有点长,把主要挖出来
[java]  view plain copy
  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. //方法有点长,把主要挖出来

 


[java]  view plain copy
  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.                        }

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

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

     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值