文件下载
文件下载最简单的方式是直接提供一个文件的 URL 地址(如 www.baidu.com/ueditor.rar),但这种方式无法控制权限。在实际开发中,通常需要用户请求一个 Servlet 地址,在 Servlet 中根据用户的权限(如是否登录)进行校验,然后读取文件并以流的方式写回给浏览器。
文件下载功能使用 HttpServletResponse 对象即可实现。
文件下载实现思路
- 获取要下载的文件的绝对路径
- 获取要下载的文件名
- 设置
content-disposition响应头控制浏览器以下载的形式打开文件 - 获取要下载的文件输入流
- 创建数据缓冲区
- 通过
response对象获取OutputStream流 - 将
FileInputStream流写入到buffer缓冲区 - 使用
OutputStream将缓冲区的数据输出到客户端浏览器
代码演示
// 1.获取要下载的文件的绝对路径
String realPath = this.getServletContext().getRealPath("/car.png");
// 2.获取要下载的文件名
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
// 3.设置content-disposition响应头控制浏览器以下载的形式打开文件
response.setHeader("content-disposition", "attachment;filename=" + fileName);
// 4.获取要下载的文件输入流
InputStream in = new FileInputStream(realPath);
int len = 0;
// 5.创建数据缓冲区,避免一次性将大文件读入内存导致内存占满
byte[] buffer = new byte[1024];
// 6.通过response对象获取OutputStream流
OutputStream out = response.getOutputStream();
// 7.将FileInputStream流写入到buffer缓冲区
while ((len = in.read(buffer)) > 0) {
// 8.使用OutputStream将缓冲区的数据输出到客户端浏览器
out.write(buffer, 0, len);
}
in.close();Code language: JavaScript (javascript)
中文文件名处理
如果文件名包含中文,需要进行 URL 编码,否则浏览器可能无法正确识别文件名:
response.setHeader("content-disposition", "attachment;filename="
+ URLEncoder.encode(fileName, "UTF-8"));Code language: JavaScript (javascript)
注意事项
- 推荐使用
OutputStream流而非PrintWriter流:OutputStream是字节流,可以处理任意类型的数据;PrintWriter是字符流,只能处理字符数据,用字符流处理字节数据(如图片、压缩包等)会导致数据丢失。 - 文件放在
WebContent目录下,可通过/文件名直接访问。
Previous: HttpServletResponse对象的介绍和解决中文输出乱码的问题
Next: 在 Servlet 中动态生成图片