文件上传下载
2021-06-28 15:06
标签:comm .net string 失败 手动 epo ast 编码格式 pre 文件上传下载功能几乎遍布于所有的软件系统中,其核心的原理机制主要是对文件流的读写处理,开发者既可以手动编写处理文件流底层的程序,也可以调用第三方开源组件提高开发效率。开发过程中常引用Apache下的commons-fileupload和commons-io组件来处理文件上传下载,组件封装了底层技术细节,使文件的上传下载功能实现变得更加简单。 由于B/S架构系统的流行趋势,开发基于Web的应用逐渐成为了开发者的首选,因此本文主要描述Java-Web文件上传下载的核心原理。 文件上传通常需要一个提交表单,该表单作为用户选择文件并上传的入口,后台服务器端会有处理文件上传的action,如下的表单信息表明:当用户选择了文件并点击提交按钮时,将以POST请求的方式提交给UploadHandleServlet处理,服务器端的UploadHandleServlet读取上传文件的信息并写入指定的存储路径。 处理文件上传的POST请求时,创建commons-fileupload组件中的DiskFileItemFactory、ServletFileUpload类,其中DiskFileItemFactory为处理文件的工厂类,可设置工厂的缓冲区大小及文件上传时生成的临时文件保存目录;ServletFileUpload是文件处理的核心类,可以解析上传文件的信息、限制上传文件的大小和文件上传容量上限并监听文件上传的进度,核心代码如下: 需要注意的是,为防止文件的覆盖,常需要产生唯一的文件名并将同一个目录下的文件打散,通过以上的文件流读写操作便可以将上传的文件存储于目标路径中,以上的注释解释了大部分技术细节,再此不再赘述。 假设以上的操作未出现异常,则文件被成功的上传至/WEB-INF/upload路径下,现在需要提供文件下载链接列表,完成文件的下载,该操作需要首先遍历服务器存储上传文件路径下的所有文件,然后渲染所有文件列表信息至页面供用户下载,所以服务器端需要读取存储文件列表的Servlet,核心代码如下: 文件下载列表页面核心代码如下: 以上即为文件下载的后台处理过程,需要注意的技术细节便是需要正确设置文件编码格式,并根据上传文件名获取真实的存储路径,底层通过读写文件流完成下载过程。 文件上传下载属于比较基础却很常用的技术,其核心就是文件的读写,但实现过程中需要注意维护文件命名的唯一性、文件的安全性(一般存储于外界无法直接访问的/WEB-INF目录下),正确设置文件格式防止中文乱码(一般统一设置编码格式为UTF-8)。实际项目中文件路径一般存储于数据库中,但为了数据安全,有时候重要文件路径需要进行加密处理,而存储的路径可以直接从数据库中读取。 文件上传下载 标签:comm .net string 失败 手动 epo ast 编码格式 pre 原文地址:http://www.cnblogs.com/google12071/p/7143239.html一 文件上传
form action="${pageContext.request.contextPath}/servlet/UploadHandleServlet" enctype="multipart/form-data" method="post">
上传用户:input type="text" name="username">br/>
上传文件1:input type="file" name="file1">br/>
上传文件2:input type="file" name="file2">br/>
input type="submit" value="提交">
form>
package com.learn.FileUploadDownload.Controller;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
/**
* 文件上传处理Servlet
* Created by lfq on 2017/7/7.
*/
public class UploadHandleServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取上传文件的保存路径,为保证数据安全性,应将文件存储于外界无法直接访问的WEB-INF目录下
String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
//上传时生成的临时文件保存目录
String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
File tempfile = new File(tempPath);
if (!tempfile.isDirectory() && !tempfile.exists()) {
System.out.println(savePath + "目录不存在,需要创建");
tempfile.mkdir();
}
String message = "";
//处理文件的工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置工厂的缓冲区大小,当上传的文件大小超过缓冲区时,就会生成一个临时文件存放至临时目录当中
factory.setSizeThreshold(1024 * 100);
//设置上传时生成的临时文件的保存目录
factory.setRepository(tempfile);
//Apache文件上传组件的文件上传解析器
ServletFileUpload fileUpload = new ServletFileUpload(factory);
//监听文件上传的进度
fileUpload.setProgressListener(new ProgressListener() {
@Override
public void update(long pByteRead, long pContextLength, int args2) {
System.out.println("文件大小为:" + pContextLength + ",当前处理:" + pByteRead);
}
});
//设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB
fileUpload.setFileSizeMax(1024 * 10124);
//设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB
fileUpload.setSizeMax(1024 * 1024 * 10);
//设置上传编码格式为UTF-8防止中文乱码
fileUpload.setHeaderEncoding("UTF-8");
//判断提交的数据是否为表单的数据
if (!ServletFileUpload.isMultipartContent(request)) {
return;
}
try {
//解析请求中上传文件的信息并返回List
二 文件下载
package com.learn.FileUploadDownload.Controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* 列出下载目录下的所有文件
* Created by lfq on 2017/7/8.
*/
public class ListFileServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取上传文件保存的目录
String fileSavePath = this.getServletContext().getRealPath("/WEB-INF/upload");
Map
c:forEach var="map" items="${fileNameMap}">
li>
c:url value="/servlet/DownLoadServlet" var="downUrl">
c:param name="fileName" value="${map.key}"> c:param>
c:url>
li>
${map.value} a href="${downUrl}">下载a>
c:forEach>
以上ListFileServlet中会递归读取服务器端存储路径下的文件信息,并以Key(fileName),Value(realName)键值对的形式存于Map,真实开发并不会这么处理,常规会将文件的路径存储于数据库中,下载时仅需从数据库中读取对应的文件存储路径即可。
提供了文件下载链接后,则必须有处理下载请求的Servlet,本案例中DownloadSevlet用于处理文件下载请求,核心代码如下:package com.learn.FileUploadDownload.Controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
/**
* 文件下载处理Servlet
* Created by lfq on 2017/7/8.
*/
public class DownLoadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取下载文件名并设置编码格式
String fileName = new String(request.getParameter("fileName").getBytes("iso8859-1"), "UTF-8");
//获取文件存储路径
String fileSavePath = this.getServletContext().getRealPath("/WEB-INF/upload");
//根据文件名搜索文件真实存储路径
String path = findFileSavePathByFileName(fileName, fileSavePath);
File file = new File(path + "\\" + fileName);
//如果文件不存在
if (!file.exists()) {
request.setAttribute("message", "您要下载的资源已被删除!!");
request.getRequestDispatcher("/message.jsp").forward(request, response);
return;
}
//获取真实文件名
String realFileName = fileName.substring(fileName.indexOf("_") + 1);
//设置响应头及文件编码格式
response.setHeader("contend-diposition", "attachment;filename=" + URLEncoder.encode(realFileName, "UTF-8"));
FileInputStream in = new FileInputStream(path + "\\" + fileName);
OutputStream out = response.getOutputStream();
byte buffer[] = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
//关闭输入流
in.close();
//关闭输出流
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
public String findFileSavePathByFileName(String fileName, String saveRootPath) {
int hashCode = fileName.hashCode();
int dir1 = hashCode & 0xf;
int dir2 = (hashCode & 0xf0) >> 4;
String fileDir = saveRootPath + "\\" + dir1 + "\\" + dir2;
File file = new File(fileDir);
if (!file.exists()) {
file.mkdirs();
}
return fileDir;
}
}
三 总结