文章目录
- 下载文件时显示文件大小
- 如果是OutputStream输出流,如何设置大小
- 扩展问题
- pdfjs预览pdf文件时遇到的问题
下载文件时显示文件大小
设置下载文件的大小
File file=new File("D:/test.txt");
response.setHeader("Accept-Ranges","bytes");
response.setHeader("Content-Length",file.length()+"");
完整小例子
/**
* 下载文件
*
* @param request
* @param response
* @throws IOException
*/
@GetMapping("/downloadFile")
public void downloadFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setCharacterEncoding("utf-8");
response.setContentType("application/octet-stream");
File file = new File("D://test3//DGSetup_Home_KZ.exe");
/**
* 设置header头显示下载文件的大小
*/
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Content-Length", file.length() + "");
String fileName = URLEncoder.encode("DGSetup_Home_KZ.exe", "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
try {
FileInputStream in = new FileInputStream(file);
// 创建输出流
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();
} catch (Exception e) {
e.printStackTrace();
}
}
可以看到下载时显示了文件的大小,在手机端同样也有同样作用,手机端确认下载前,会提示文件的大小。
如果是OutputStream输出流,如何设置大小
直接使用response.getOutputStream输出流进行输出时,是不能获取输出流或者输出文件的大小。
解决办法也有很多
- 方法1(略) 将输出流写入临时文件,再File对象的length方法获取文件大小;缺点,需要使用到临时文件,存在频繁的磁盘操作
- 方法2(如下示例) 不直接输出到response.getOutputStream,先利用ByteArrayOutputStream接收,再使用ByteArrayInputStream 读取,使用InputStream的available方法获取输出流的字节大小。然后再输出到response.getOutputStream
try {
/**
*直接将输出流输出到response.getOutputStream时,前端无法显示下载文件的大小,可以通创建ByteArrayOutputStream接收,
* 再利用ByteArrayInputStream读取,再输出到response.getOutputStream流,这样可以支持显示文件的大小,但是不适合较大文件,
* 因为数据流存储在内容中,经过一次转换才转发出去
*
*/
//PdfUtil.output(templateFile, dataMap, picMap, checkboxMap, response.getOutputStream());
ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
PdfUtil.output(templateFile, dataMap, picMap, checkboxMap, outputStream);
ByteArrayInputStream in=new ByteArrayInputStream(outputStream.toByteArray());
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Content-Length", in.available() + "");
// FileInputStream in = new FileInputStream(file);
// 创建输出流
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();
} catch (Exception e) {
e.printStackTrace();
}
扩展问题
pdfjs预览pdf文件时遇到的问题
使用pdfjs预览pdf文件时,不要返回文件大小,因为pdfjs会判断文件的长度,会发生控制台错误,文件大小不一致,所以建议在预览时不返回长度给前端,只有文件下载时返回文件的大小。
完整示例
/**
* 下载文件、预览文件
*
* @param request
* @param response
* @throws IOException
*/
@GetMapping("/downloadFile")
public void downloadFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setCharacterEncoding("utf-8");
response.setContentType("application/octet-stream");
File file = new File("D://test3//abc.pdf");
/**
* 设置header头显示下载文件的大小
*/
String showType=request.getParameter("showType"); //download 下载,preview下载
if(showType.equals("download")){
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Content-Length", file.length() + "");
String fileName = URLEncoder.encode("abc.pdf", "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
}else{
String fileName = URLEncoder.encode("abc.pdf", "UTF-8");
response.setHeader("Content-Disposition", "inline;filename=" + fileName);
}
try {
FileInputStream in = new FileInputStream(file);
// 创建输出流
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();
} catch (Exception e) {
e.printStackTrace();
}
}