web浏览器文件上传的问题

本文详细介绍了文件上传的概念、要素和常见技术,如JSPSmartUpload、FileUpload及Struts2中的实现。通过实例展示了如何使用Servlet处理文件上传,包括设置表单、解析请求、保存文件等步骤,并提出了文件上传时的目录分离策略以解决文件过多的问题。同时,分析了目录分离的算法,确保文件有效管理和高效访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文件上传的技术

1. JSPSmartUpload(应用在JSP上的文件上传和下载的组件)

2. FileUpload(应用在Java环境上的文件上传的功能)

3. Struts2(提供文件上传的功能)

什么是文件上传

将本地的文件通过流写入到服务器的过程

文件上传的要素

表单的提交的方式需要是POST

表单中需要有<input type=”file”>元素,需要有name属性和值。

表单form的属性enctype=”multipart/form-data”

 代码演示

jsp部分代码

	<form action="填写提交的路径" method="post" enctype="multipart/form-data">
		<input type="text" name="textName">
		<input type="file" name="filename">
		<input type="submit" value="提交">
	</form>

 UploadFileServlet代码(mvc中控制器的代码)

需要引入两个jar包:commons-fileupload-1.2.1.jar和commons-io-1.4.jar

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import utils.UploadUtils;
/**
 * 文件上传
 */
@WebServlet("/uploadFileServlet")
public class UploadFileServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//判断enctype填写的格式是否正确
		if(!ServletFileUpload.isMultipartContent(request)) {
			request.setAttribute("msg", "提交的格式enctry错误");
			request.getRequestDispatcher("/jsp/upload.jsp").forward(request, response);
		}
		try {
			// 1.创建磁盘文件项工厂
			DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
			//1.1缓冲区的大小为3M
			diskFileItemFactory.setSizeThreshold(3*1024*1024);
			//1.2临时文件的存放位置
			String repositoryPath = getServletContext().getRealPath("/repositoryFile");
			diskFileItemFactory.setRepository(new File(repositoryPath));
			// 2.创建核心解析类
			ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
			//2.1设置文件的上传大小
			servletFileUpload.setSizeMax(20*1024*1024); //总文件
			servletFileUpload.setFileSizeMax(6*1024*1024);//单个文件
			// 3.利用核心类解析Request,解析后会得到多个部分。返回一个List集合。List集合装的是每个部分的内容(FileItem文件项)。
			List<FileItem> list = servletFileUpload.parseRequest(request);
			// 4.遍历List集合,会得到代表每个部分的文件项的对象。根据文件项判断是否是文件上传项。
			for (FileItem fileItem : list) {
				if (fileItem.isFormField()) {
					// 普通文件
					String name = fileItem.getFieldName();
					String value = fileItem.getString();
					System.out.println(name + "  " + value);
				} else {
					String nameFile = fileItem.getName();
					//IE老版本的文件名带用户上传全路径
					int indexFileName=nameFile.lastIndexOf("\\");
					if(indexFileName!=-1) {
						nameFile=nameFile.substring(indexFileName+1);
					}
					// 获得文件上传的文件的数据:
					InputStream inputStream = fileItem.getInputStream();
					// 获得文件上传的路径:磁盘绝对路径。
					String realPath = getServletContext().getRealPath("/upload");
					//获取唯一的文件名字
					String uuidFileName=UploadUtils.getUuidFileName(nameFile);
					//进行目录分离:
					String uuidFilePath=UploadUtils.getRealPath(uuidFileName);
					String newPath=realPath+uuidFilePath;
					File file=new File(newPath);
					if(!file.exists()) {
						file.mkdirs();
					}
					// 创建一个输出流,写入到设置的路径中。
					FileOutputStream ou = new FileOutputStream(newPath+"\\"+uuidFileName);
					int len = 0;
					byte[] a = new byte[1024];
					// 两个流对接:
					while ((len = inputStream.read(a)) != -1) {
						ou.write(a, 0, len);
					}
					inputStream.close();
					ou.close();
				}
				//删除缓冲区的文件(临时文件)
				fileItem.delete();
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

utils代码

import java.util.UUID;

public class UploadUtils {
    //传入文件名,返回唯一路径
	public static String getUuidFileName(String filename) {
		String uuid=UUID.randomUUID().toString().replace("-", "");
		int indexdot=filename.lastIndexOf(".");
		String newFilename=uuid+filename.substring(indexdot);
		return newFilename;
	}
    //目录分离
	public static String getRealPath(String uuidFilename) {
		//获取的是二级目录,可以增加
		int code1 = uuidFilename.hashCode();
		int d1 = code1 & 0xf;
		int code2 = code1 >>> 4;
		int d2 = code2 & 0xf;
		return "/"+d1+"/"+d2;
		
	}
	

}

文件上传的原理分析

文件上传到同一个目录下(文件过多的问题) 

问题描述

现在所有的用户都上传文件,如果网站访问量比较大,如果都上传到同一个目录下,在同一个目录下存放的文件太多了,也会对程序有影响(其实打开该目录的时候,都会很卡,更别说读写操作)。

文件解决

目录分离

按时间分离 :按月、周、天、小时。

按用户分离 :按张三、李四。

按个数分离 :一个目录下存放3000个文件。

按目录分离算法 :按照某种特定算法进行分离。

唯一文件名获取其hashCode值,返回int类型的值(32位)

让hashCode的值 & 0xf,得出的这个值作为一级目录。

让hashCode右移4位  再& 0xf,得出的这个值作为二级目录。

以此类推。

分析算法:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值