最近想要分享一个在线下载的数据文件,开始选用了用了 Commons IO 包中的 FileUtils ,具体方式如下
@RequestMapping("download")
public ResponseEntity<byte[]> download(String filename,HttpServletRequest request) throws IOException{
String path = request.getServletContext().getRealPath("WEB-INF/data/");
File file = new File(path + filename);
HttpHeaders headers=new HttpHeaders();
headers.setContentDispositionFormData("attachment",URLEncoder.encode(filename,"UTF-8"));
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.OK);
}
这种方式下载小于20MB的文件还行,再大的就会报错 ,报错信息:java.lang.OutOfMemoryError: Java heap space
原因在于FileUtils.readFileToByteArray 会把文件一次性读入内存中,当文件的大小超过JVM和Tomcat的内存配置时就会OutOfMemory
所以改用了将文件流分字节段输出的方式
@RequestMapping("download")
public void download(String filename,HttpServletRequest request,HttpServletResponse response) throws IOException{
String path = request.getServletContext().getRealPath("WEB-INF/data/");
File file = new File(path + filename);
response.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(filename,"UTF-8"));
response.addHeader("Content-Type","application/json;charset=UTF-8");
try(
InputStream is = new FileInputStream(file);
OutputStream os = response.getOutputStream();
){
int read = 0;
byte[] bytes = new byte[2048];
while ((read = is.read(bytes)) != -1)
os.write(bytes, 0, read);
}