一、文件上传中要注意的9个问题
方式一:当前日期建立一个文件夹,当前上传的文件都放到此文件夹中。
例如:生成一个2014-10-6的文件夹
Date date = new Date(); DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM); String s = df.format(date); String path = storePath+"\\"+s; File file = new File(path); if(!file.exists()) { file.mkdirs();//创建多级目录,mkdir只创建一级目录 } return path;//文件夹的地址
方式二:利用文件名的hash码打散目录来存储。
通过判断其Mime类型才靠谱。FileItem.getContentType();
抓异常进行提示:org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException
if(fileName==null||"".equals(fileName.trim())){ continue; }
public void update(long pBytesRead, long pContentLength, int pItems) { System.out.println("已读取:"+pBytesRead+",文件大小:"+pContentLength+",第几项:"+pItems); }
完整实例 :
表单:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP '1.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form action="${pageContext.request.contextPath}/servlet/UploadServlet3" method="post" enctype="multipart/form-data"> 用户名<input type="text" name="username"/> <br/> <input type="file" name="f1"/><br/> <input type="file" name="f2"/><br/> <input type="submit" value="保存"/> </form> </body> </html>
UploadServlet3
package com.mair.upload; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.text.DateFormat; import java.util.Date; import java.util.List; import java.util.UUID; import java.util.logging.SimpleFormatter; 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.ProgressListener; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; public class UploadServlet3 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置编码 request.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); PrintWriter pw = response.getWriter(); try { //设置系统环境 DiskFileItemFactory factory = new DiskFileItemFactory(); //文件存储的路径 String storePath = getServletContext().getRealPath("/WEB-INF/files"); //判断传输方式 form enctype=multipart/form-data boolean isMultipart = ServletFileUpload.isMultipartContent(request); if(!isMultipart) { pw.write("传输方式有错误!"); return; } ServletFileUpload upload = new ServletFileUpload(factory); upload.setFileSizeMax(4*1024*1024);//设置单个文件大小不能超过4M upload.setSizeMax(4*1024*1024);//设置总文件上传大小不能超过6M //监听上传进度 upload.setProgressListener(new ProgressListener() { //pBytesRead:当前以读取到的字节数 //pContentLength:文件的长度 //pItems:第几项 public void update(long pBytesRead, long pContentLength, int pItems) { System.out.println("已读去文件字节 :"+pBytesRead+" 文件总长度:"+pContentLength+" 第"+pItems+"项"); } }); //解析 List<FileItem> items = upload.parseRequest(request); for(FileItem item: items) { if(item.isFormField())//普通字段,表单提交过来的 { String name = item.getFieldName(); String value = item.getString("UTF-8"); System.out.println(name+"=="+value); }else { // String mimeType = item.getContentType(); 获取上传文件类型 // if(mimeType.startsWith("image")){ InputStream in =item.getInputStream(); String fileName = item.getName(); if(fileName==null || "".equals(fileName.trim())) { continue; } fileName = fileName.substring(fileName.lastIndexOf("\\")+1); fileName = UUID.randomUUID()+"_"+fileName; //按日期来建文件夹 String newStorePath = makeStorePath(storePath); String storeFile = newStorePath+"\\"+fileName; OutputStream out = new FileOutputStream(storeFile); byte[] b = new byte[1024]; int len = -1; while((len = in.read(b))!=-1) { out.write(b,0,len); } in.close(); out.close(); item.delete();//删除临时文件 } } // } }catch(org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException e){ //单个文件超出异常 pw.write("单个文件不能超过4M"); }catch(org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException e){ //总文件超出异常 pw.write("总文件不能超过6M"); }catch (FileUploadException e) { e.printStackTrace(); } } //用日期生成的目录,如果想用hashcode,后面 private String makeStorePath(String storePath) { Date date = new Date(); DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM); String s = df.format(date); String path = storePath+"\\"+s; File file = new File(path); if(!file.exists()) { file.mkdirs();//创建多级目录,mkdir只创建一级目录 } return path; } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
用hashcode生成目录:只需要改写一下makeStorePath(String storePath, String fileName)函数
private String makeStorePath(String storePath, String fileName) { int hashCode = fileName.hashCode(); int dir1 = hashCode & 0xf;// 0000~1111:整数0~15共16个 int dir2 = (hashCode & 0xf0) >> 4;// 0000~1111:整数0~15共16个 String path = storePath + "\\" + dir1 + "\\" + dir2; // WEB-INF/files/1/12 File file = new File(path); if (!file.exists()) file.mkdirs(); return path; }