文件上传下载

Posted ljbguanli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件上传下载相关的知识,希望对你有一定的参考价值。

文件上传下载原理

在TCP/IP中。最早出现的文件上传下载机制是FTP,它是将文件由server的标准机制。

可是在JSP编程中不能使用FTP方法来上传文件,这是由JSP执行机制决定的。

上传原理:

通过为表单元素设置method="post" enctype="multippart/form-data"属性,让表单提交的数据以二进制编码
方式提交。在接收此请求的Servlet中用二进制流来获取内容。就能够取得上传文件的内容。从而实现文件的上传

enctype属性:
applic ation/x-www-form-urlencoded:默认,仅仅处理表单域里的value属性值,将表单域里的属性值处理成url编码方式。
multipart/form-data:表单以二进制流的方式来处理表单数据,会把文件域指定的内容也封装到请求參数里 
text/plain:主要适用于通过表单发送邮件的方式

下载原理:

步骤1:HttpServletResponse.setContentType方法来设置Content-type头字段的值,为浏览器无法使用某种方式或激活某个程序来处理MIME类型,如"application/octet-stream"或"application/x-msddownload"
步骤2:通过HttpServletResponse..setHeader方法设置Content-Disposition头的值为"attachment;filename=文件名称"
步骤3:读取下载文件,调用HttpServelResponse.getOutputStream方法返回的ServletOutputStream对象来向client写入附件文件内容。


实现文件上传下载的方法有非常多种:

JSP+Sevlet,SmartUpload,FileUpload。Struct2

此处具体说明FileUpload实现上传下载的方法。

上传:

/ 设置文件保存路径
		String savePath = this.getServletContext().getRealPath(
				"/WEB-INF/upload");

DiskFileItemFactory factory = new DiskFileItemFactory();// 磁盘对象
			File file = new File(this.getServletContext().getRealPath(
					"/WEB-INF/temp"));
			// 假设文件夹不存在。则创建一个新的
			if (!file.exists()) {
				file.mkdirs();
			}
			factory.setSizeThreshold(1024 * 8); // 8k的缓冲区,文件大于8K则保存到暂时文件夹
			factory.setRepository(file);// 用暂时文件保存解析出来的数据
			ServletFileUpload upload = new ServletFileUpload(factory);// 声明解析的request对象
			// 推断是普通表单。还是带文件上传的表单。文件上传的表单值不能按普通表单接收值那样直接获取
			if (!ServletFileUpload.isMultipartContent(request)) {
				return;
			}
			upload.setFileSizeMax(1024 * 1024 * 5);// 设置每一个文件的大小不能超过10M
			upload.setSizeMax(1024 * 1024 * 50);// 设置一共上传的文件大小不能超过50M
			List<FileItem> list = upload.parseRequest(request);// 把每一个提交的表单项打包成一个list
			for (FileItem item : list) {
				// 推断为普通的表单输入域还是文件输入域
				if (item.isFormField()) {
					return;
				} else {
					String filename = item.getName();
					if (filename == null || filename.trim().equals("")) {
						continue;
					}
					// 截取文件名称
					filename = filename
							.substring(filename.lastIndexOf("\\") + 1);
					InputStream in = item.getInputStream();
					// 防止文件覆盖
					String saveFilename = makeFileName(filename);
					// 真正的存储路径
					String realSavePath = makePath(saveFilename, savePath);
					String allPath = realSavePath + "\\" + saveFilename;

					attach.setAttachTitle(saveFilename);
					attach.setAttachPath(allPath);
					// 向数据库中插入数据
					attachService.addAttach(attach, fareId);

					request.setAttribute("fareId", fareId);
					FileOutputStream out = new FileOutputStream(allPath);
					byte buffer[] = new byte[1024];
					int len = 0;
					while ((len = in.read(buffer)) > 0) {
						out.write(buffer, 0, len);
					}
					in.close();
					out.close();
					item.delete();
				}
1.??为什么要

factory.setRepository(new File(this.getServletContext().getRealPath("/WEB-INF/temp")));//设置暂时文件路径

由于当从没有调用此方法设置暂时文件存储文件夹时,默认採用系统默认的暂时文件路径。能够通过系统属性 java.io.tmpdir 获取。例如以下代码:

System.getProperty("java.io.tmpdir");
Tomcat系统默认暂时文件夹为“<tomcat安装文件夹>/temp/”。

Apache文件上传组件在解析上传数据中的每一个字段内容时,须要暂时保存解析出的数据,以便在后面进行数据的进一步处理(保存在磁盘特定位置或插入数据库)。由于Java虚拟机默认能够使用的内存空间是有限的。超出限制时将会抛出“java.lang.OutOfMemoryError”错误。

假设上传的文件非常大,比如800M的文件。在内存中将无法暂时保存该文件内容。Apache文件上传组件转而採用暂时文件来保存这些数据;但假设上传的文件非常小,比如600个字节的文件,显然将其直接保存在内存中性能会更加好些。

2.当前台input的type="file"时就会有默认的button“选择文件(未选择文件)”或者“浏览”界面。其界面样式依据不同的浏览器而定。点击button就会弹出文件上传的窗体。

下载:

弹框:response.setHeader("content-disposition", "attachment;filename="+ URLEncoder.encode(realname, "UTF-8"));


以上是关于文件上传下载的主要内容,如果未能解决你的问题,请参考以下文章

Alamofire 文件上传出现错误“JSON 文本未以数组或对象开头,并且允许未设置片段的选项”

使用 libtorrent 下载特定片段

根据图片的url地址下载图片到本地保存代码片段

Xamarin Android 片段库

将存储在内存中的文件上传到s3

片段中的Firebase数据不是持久的,会重新下载