最近处理文件下载遇到奇怪的现象:小文件(30 ~ 40M)下载正常,大文件(>100M)下载总是404
因为使用了Nginx,最初怀疑是代理配置的问题,于是
proxy_buffering off
或
proxy_buffering on;
proxy_buffers 4 4k;
proxy_busy_buffers_size 8k;
proxy_max_temp_file_size 1024m;
并
proxy_send_timeout 600;
proxy_read_timeout 600;
结果没卵用,再细想404 是服务报出来的,于是专心改代码
最初代码如下
<a href='project/downloadFile?fileName=fn.docx&filePath=c:\\dir\\fn.docx' target='_self'>下载fn.docx</a>
@RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
@ResponseBody
public void downloadFile(HttpServletRequest request, HttpServletResponse response) {
try {
String fileName = new String(
request.getParameter("fileName").getBytes("iso-8859-1"),
"UTF-8"
);
String filePath = new String(
request.getParameter("filePath").getBytes("iso-8859-1"),
"UTF-8"
);
File file = new File(filePath);
if (!file.exists()) {
return;
}
InputStream input = new FileInputStream(file);
byte[] buffer = new byte[input.available()];
input.read(buffer);
input.close();
response.reset();
response.setHeader(
"Content-disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")
);
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
OutputStream output = response.getOutputStream();
output.write(buffer);
output.flush();
output.close();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
改成如下代码就好了
@RequestMapping(value = "/downloadFile", method = RequestMethod.GET)
@ResponseBody
public void downloadFile(HttpServletRequest request, HttpServletResponse response) {
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
String fileName = new String(
request.getParameter("fileName").getBytes("iso-8859-1"),
"UTF-8"
);
String filePath = new String(
request.getParameter("filePath").getBytes("iso-8859-1"),
"UTF-8"
);
File file = new File(filePath);
if (!file.exists()) {
return;
}
input = new BufferedInputStream(new FileInputStream(file));
response.setHeader(
"Content-disposition",
"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")
);
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
ServletOutputStream servlet = response.getOutputStream();
output = new BufferedOutputStream(servlet);
byte[] buffer = new byte[2048];
int len = 0;
while ((len = input.read(buffer, 0, buffer.length)) != -1) {
output.write(buffer, 0, len);
}
output.flush();
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
try {
if (null != output) {
output.close();
}
if (null != input) {
input.close();
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}
我只是知其然,不知道所以然,不明白
ServletOutputStream 和 OutputStream 有啥区别?