JavaWeb之文件上传篇,

文件上传的意思就是通过浏览器将文件上传到服务器

文件上传的步骤:

1、需要准备一个表单,这个表单的enctype属性的值必须是multipart/form-data,并且 请求的方式需要是 post , 并且有个 input输入项的
type=”file” name="file"

2、需要去写一个服务器端程序 来解析上传的数据, 将数据 保存起来 ..


那么要怎么解析上传的数据, 将数据 保存起来呢???

第一步,创建一个磁盘文件项工厂 new DiskFileItemFactory()

第二步,创建核心上传类 new ServletFileUpload(FileItemFactory fileItemFactory)

第三步,使用核心上传类里面方法解析request对象,得到文件上传项。

第四步,返回list集合,集合里面的每一个部分都是FileItem,判断普通输入项还是文件上传项

第五步,如果是一个普通输入项,输出内容,如果使用文件上传项,执行上传的操作(写上传的代码)

代码实现:

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		try {
			// 第一步创建一个磁盘文件项工厂
			DiskFileItemFactory factory = new DiskFileItemFactory();
			//设置临时空间的大小,和临时文件的存储路径, 如果上传的文件大于1M,则保存到临时目录
			factory.setSizeThreshold(1*1024*1024);//单位是字节
			String realPath = getServletContext().getRealPath("/temp");
			factory.setRepository(new File(realPath));
			// 第二步,创建核心上传类 new ServletFileUpload(FileItemFactory
			// fileItemFactory)
			ServletFileUpload upload = new ServletFileUpload(factory);
			//設置单个文件上传的大小,最大是1M
			upload.setFileSizeMax(100*1024*1024);
			upload.setHeaderEncoding("utf-8");
			// 第三步,使用核心上传类里面方法解析request对象,得到文件上传项
			List<FileItem> list = upload.parseRequest(request);
			//遍历集合判断是普通输入项还是文件上传项
			for (FileItem fileItem : list) {
				//如果是普通输入项
				if (fileItem.isFormField()) {
					String name = fileItem.getString("utf-8");
					System.out.println("上传人的姓名 : " + name);
				} else {
					//文件上传项
					//获得文件的名字
					String fieldName = fileItem.getName();
					
					//生成随机字符串
					String uuid = UUID.randomUUID().toString();
					fieldName = uuid + "-" + fieldName;
					//怼上输入流读取文件中的内容
					InputStream in = fileItem.getInputStream();
					//得到uploadfile的完全路径,为了把上传来的文件存到服务器
					String path = getServletContext().getRealPath("/uploadfile");
					System.out.println("路径 :" + path);
					
					//得到分离后的目录
					String url = UploadUtils.getPath(fieldName);
					
					//现在路径是不存在的, 需要创建
					File file = new File(path+url);
					
					//如果不存在, 创建
					if (!file.exists()) {
						file.mkdirs();
					}
					OutputStream out = new FileOutputStream(path + url + "/" +fieldName);
					//流对接
					int len = 0;
					byte[] b = new byte[1024];
					//把从输入流中读取的数据存到字节数组b中,返回实际读取的字节数len
					while ((len = in.read(b)) != -1) {
						//将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
						out.write(b, 0, len);
					}
					in.close();
					out.close();
					//删除临时文件
					fileItem.delete();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
这里需要解释的是一下setSizeThreshold(int sizeThreshold):设置临时空间的大小

之所以会有这个方法是因为Apache文件上传组件在解析上传数据中的每个字段内容时,需要临时保存解析出的数据,以便在后面进行数据的进一步处理(保存在磁盘特定位置或插入数据库)。因为Java拟机默认可以使a虚时保存该文件内容,Apache文件上用的内存空间是有限的,超出限制时将会抛出“java.lang.OutOfMemoryError”错误。如果上传的文件很大,例如800M的文件,在内存中将无法保存如此大的文件转而采用临时文件来保存这些数据;但如果上传的文件很小,例如600个字节的文件,显然将其直接保存在内存中性能会更加好些。


getServletContext().getRealPath()的意思就是得到web项目里某个文件或者某个文件夹的完全路径


上传的问题的解决
=====================
第一个问题:如果上传了相同名称的文件,最后一次上传的文件会覆盖之前的文件
** 解决方法:在文件名里面添加随机的字符串
*** 生成唯一的随机的字符串,使用工具类UUID
** 在文件名之前添加随机的字符串: 随机字符串_1.txt

====================== 






猜你喜欢

转载自blog.csdn.net/leng1235/article/details/50812027