在文件下载时返回字节数组或servlet输出流之间是否存在差异?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在文件下载时返回字节数组或servlet输出流之间是否存在差异?相关的知识,希望对你有一定的参考价值。
我想知道当Sprin MVC控制器方法返回字节数组byte[]
来表示下载文件或将InputStream
对象复制到ServletOutputStream
对象时是否存在真正的差异?
我问的原因是我必须确保在下载大文件时不会出现任何OutOfMemory错误。通过ServletOutputStream
的传递文件是否有助于避免它?
传递字节数组:
byte[] download() {
return getUrlContentAsByteArray();
}
传入ServletOutputStream:
void download(HttpServletResponse response) {
InputStream content = getUrlContentAsStream();
ServletOutputStream outputStream = response.getOutputStream();
response.reset();response.setContentType(ContentType.APPLICATION_OCTET_STREAM.getMimeType());
IOUtils.copyLarge(inputStream, outputStream);
}
答案
在第一个示例中,您必须将整个响应读入内存并将其存储在字节数组中。这将至少需要与响应大小一样多的内存。
在第二个示例中,您不会立即将整个响应保留在内存中,而是使用IOUtils.copy
将来自源的多个小块内容复制到servlet响应中。默认情况下,IOUtils使用4kB大缓冲区。但是,您使用的是Spring和Servlet API的奇怪组合。
单独使用Spring MVC,您可以省略servlet API,返回包装为Resource的InputStream,让Spring为您执行复制作业:
@RequestMapping(value = "/download", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<Resource> download() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
InputStream is = null; // get your input stream here
Resource resource = new InputStreamResource(is);
return new ResponseEntity<>(resource, headers, HttpStatus.OK);
}
以上是关于在文件下载时返回字节数组或servlet输出流之间是否存在差异?的主要内容,如果未能解决你的问题,请参考以下文章