在工作中使用RestTemplate调用接口下载资源文件时,使用exchange方法返回ResponseEntity<byte[]>接收资源流,遇到大文件照成内存溢出的问题,如下图代码:
ResponseEntity<byte[]> result = restTemplate.exchange(url, HttpMethod.GET, null , byte[].class);
byte[] body = result.getBody();
File file = new File( FILE_PATH + cloudDataEntity.getProjectName() + ".7z");
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(body);
} catch (Exception e) {
e.printStackTrace();
}finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
后面对代码进行了优化,对响应进行流式处理而不是将其全部加载到内存中。代码如下:
//定义请求头的接收类型
RequestCallback requestCallback = request -> request.getHeaders()
.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
//对响应进行流式处理而不是将其全部加载到内存中
try {
restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
Files.copy(clientHttpResponse.getBody(), Paths.get(FILE_PATH + cloudDataEntity.getProjectName() + ".7z"));
return null;
});
} catch (RestClientException e) {
e.printStackTrace();
});
}