上传文件之目录处理

1. 文件必须保存到WEB-INF下!
  * 目的是不让浏览器直接访问到!
  * 把文件保存到WEB-INF目录下!
2. 文件名称相关问题
 * 有的浏览器上传的文件名是绝对路径,这需要切割!C:\files\baibing.jpg
        String filename = fi2.getName();
int index = filename.lastIndexOf("\\");
if(index != -1) {
   filename = filename.substring(index+1);
}
  * 文件名乱码或者普通表单项乱码:request.setCharacterEncoding("utf-8");因为fileupload内部会调用request.getCharacterEncoding();
> request.setCharacterEncoding("utf-8");//优先级低
> servletFileUpload.setHeaderEncoding("utf-8");//优先级高
  * 文件同名问题;我们需要为每个文件添加名称前缀,这个前缀要保证不能重复。uuid
> filename = CommonUtils.uuid() + "_" + filename;
3. 目录打散
  * 不能在一个目录下存放之多文件。
    > 首字符打散:使用文件的首字母做为目录名称,例如:abc.txt,那么我们把文件保存到a目录下。如果a目录这时不存在,那么创建之。
    > 时间打散:使用当前日期做为目录。
    > 哈希打散:
      * 通过文件名称得到int值,即调用hashCode()
      * 它int值转换成16进制0~9, A~F

      * 获取16进制的前两位用来生成目录,目录为二层!例如:1B2C3D4E5F,/1/B/保存文件。

public class Upload3Servlet extends HttpServlet {

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		/*
		 * 上传三步
		 */
		// 工厂
		DiskFileItemFactory factory = new DiskFileItemFactory(20*1024, new File("F:/f/temp"));
		// 解析器
		ServletFileUpload sfu = new ServletFileUpload(factory);
		
		// 解析,得到List
		try {
			List<FileItem> list = sfu.parseRequest(request);
			FileItem fi = list.get(1);
			
			
			//////////////////////////////////////////////////////
			
			/*
			 * 1. 得到文件保存的路径
			 */
			String root = this.getServletContext().getRealPath("/WEB-INF/files/");
			/*
			 * 2. 生成二层目录
			 *   1). 得到文件名称
			 *   2). 得到hashCode
			 *   3). 转发成16进制
			 *   4). 获取前二个字符用来生成目录
			 */
			String filename = fi.getName();//获取上传的文件名称
			/*
			 * 处理文件名的绝对路径问题
			 */
			int index = filename.lastIndexOf("\\");
			if(index != -1) {
				filename = filename.substring(index+1);
			}
			/*
			 * 给文件名称添加uuid前缀,处理文件同名问题
			 */
			String savename = CommonUtils.uuid() + "_" + filename;
			
			/*
			 * 1. 得到hashCode
			 */
			int hCode = filename.hashCode();
			String hex = Integer.toHexString(hCode);
			
			/*
			 * 2. 获取hex的前两个字母,与root连接在一起,生成一个完整的路径
			 */
			File dirFile = new File(root, hex.charAt(0) + "/" + hex.charAt(1));
			
			/*
			 * 3. 创建目录链
			 */
			dirFile.mkdirs();
			
			/*
			 * 4. 创建目录文件
			 */
			File destFile = new File(dirFile, savename);
			
			/*
			 * 5. 保存
			 */
			fi.write(destFile);
			
			///////////////////////////////////////////////////////
			
		} catch (Exception e) {
			 throw new RuntimeException(e);
		} 
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值