`
lapulande
  • 浏览: 219597 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

阅读更多

昨天做了一个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的原因了吧。。

 

 

分享到:
评论
1 楼 lf84730258 2010-08-26  
呵呵..但是其实这个组件似乎还有一点小问题.- -

相关推荐

    开发工具 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开发工具 commons-fileupload-1.3.2...

    commons-fileupload-1.3.3.jar和commons-io-2.6.jar

    总的来说,`commons-fileupload-1.3.3.jar`和`commons-io-2.6.jar`是Java开发中不可或缺的工具,它们大大简化了文件上传的实现,同时也提供了良好的错误处理和资源管理机制,使得文件上传操作变得更加可靠和高效。...

    commons-fileupload-1.4-API文档-中文版.zip

    赠送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-fileupload-1.2.1.jar 和commons-io-1.4.jar

    在实际开发中,当你需要在Web应用中实现文件上传功能时,首先会配置`commons-fileupload-1.2.1.jar`来解析请求,然后利用`commons-io-1.4.jar`处理上传后的文件,比如保存到服务器的指定目录,或者进行一些预处理...

    commons-fileupload-1.3.2.jar和commons-io-2.5.jar

    在使用`commons-fileupload-1.3.2.jar`处理文件上传时,通常会配合`commons-io-2.5.jar`来完成一些辅助操作,例如读取上传文件的内容、检查文件类型、移动文件到目标位置等。通过这两个库的组合,开发者能够方便地在...

    commons-fileupload.jar和commons-io.jar

    然后在Controller中,可以直接通过`@RequestParam("file") MultipartFile file`来接收上传的文件,这里MultipartFile就是由`commons-fileupload`和`commons-io`支持的。 对于MyBatis,虽然它主要关注数据库操作,但...

    commons commons-fileupload历史版本jar包集合

    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-...

    java+servlet+commons-io-2.4.jar+commons-fileupload-1.3.jar实现文件的上传与下载

    在Java Web开发中,文件的上传与下载是常见的功能需求,尤其...通过以上步骤,你可以实现基于Java Servlet和Apache Commons库的文件上传与下载功能。理解并熟练掌握这些知识点,对于开发高效、稳定的Web应用至关重要。

    文件上传两个jar包commons-fileupload-1.3.1和commons-io-2.4

    在这个场景中,`commons-fileupload-1.3.1.jar` 和 `commons-io-2.4.jar` 是两个至关重要的库,它们提供了强大的文件上传支持。 `commons-fileupload-1.3.1.jar` 是Apache Commons FileUpload项目的实现,这是一个...

    commons-fileupload-1.3.3.jar commons-io-2.5.jar

    `commons-fileupload-1.3.3.jar` 和 `commons-io-2.5.jar` 是Apache Commons项目中的两个重要库,它们提供了强大的文件上传功能,使得开发者可以轻松地处理用户通过表单提交的文件。 Apache Commons FileUpload是...

    commons-fileupload-1.3.jar和commons-io-1.2.jar.zip

    在这个场景中,我们关注的是"commons-fileupload-1.3.jar"和"commons-io-1.2.jar"这两个文件,它们被打包在一个名为"commons-fileupload-1.3.jar和commons-io-1.2.jar.zip"的压缩文件中。 **Apache Commons ...

    commons-fileupload-1.2.2.jar和commons-io-2.4.jar包

    总之,`commons-fileupload-1.2.2.jar`和`commons-io-2.4.jar`是Java Web开发中处理文件上传和下载不可或缺的工具。尽管它们的版本可能不是最新的,但依然能提供可靠的功能,并且在很多现有的系统中广泛使用。理解并...

    commons-fileupload-1.3.3-API文档-中文版.zip

    赠送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-1.3.2jar包和commons-io-2.5jar包.zip

    Apache Commons FileUpload与Apache Commons IO是Java开发中处理文件上传和I/O操作的重要库。这两个库在处理Web应用,特别是基于JSP(JavaServer Pages)的文件上传功能时,扮演着核心角色。在这个主题中,我们将...

    commons-fileupload-1.3.2jar和commons-io-2.5.jar包

    Apache Commons FileUpload和Commons IO库提供了强大的支持,使得开发者能够方便地处理客户端上传的文件。这里我们将深入探讨这两个jar包的功能、使用方法以及它们如何与JSP(JavaServer Pages)结合。 `commons-...

    commons-fileupload-1.3.3.jar和commons-io-1.3.2.jar程序文件

    标题中的"commons-fileupload-1.3.3.jar"和"commons-io-1.3.2.jar"是两个在Java开发中广泛使用的开源库,分别用于处理HTTP协议下的文件上传和一般I/O操作。这两个库是由Apache软件基金会提供的,属于Apache Commons...

    commons-fileupload实现文件上传下载

    ### Commons-FileUpload 实现文件上传下载 #### 知识点概述 Commons-FileUpload 是 Apache 提供的一个用于处理 HTTP 文件上传的组件。它基于 Servlet 规范,并且能够解析来自 `multipart/form-data` 编码类型的 ...

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

    总结来说,`commons-fileupload-1.2.1.jar`和`commons-io-1.3.2.jar`是Java Web应用中处理文件上传的必备工具,它们提供了丰富的功能和良好的性能,简化了开发流程,使开发者可以专注于业务逻辑而不是底层细节。

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

    在处理文件上传时,`commons-fileupload`可能会依赖`commons-io`来完成一些底层的文件操作,比如读写文件、复制文件、检查文件是否存在等。`1.3.2`同样表示这个库的一个特定版本,它可能包含了更多的功能和改进。 ...

    commons-fileupload.rar;包括commons-fileupload-1.3.1-bin和commons-io-2.4

    Commons FileUpload是Apache软件基金会的一...在实际开发中,结合`commons-fileupload`和`commons-io`这两个库,可以方便地实现在Java Web应用中的文件上传功能,并且可以自定义各种策略以满足特定的安全性和性能要求。

Global site tag (gtag.js) - Google Analytics