У нас есть веб-приложение с клиентом в agnular.js и сервером в java spring. Я работаю над функциональностью загрузки этого файла журнала, т.е. logs.tar с клиента.
В настоящее время мы используем blob для загрузки. Наша проблема заключается в том, что если размер этого журнала станет огромным, например, более 2 ГБ, то при потоковой передаче он создаст нагрузку на память приложения. поэтому я хочу загружать большие файлы по частям, а не загружать весь большой двоичный объект в память. подскажите пожалуйста выход.
Java-код на стороне сервера -
public ResponseEntity<?> downloadLogs(HttpServletRequest request) {
File file = preferencesService.downloadLogs();
if (file != null) {
FileInputStream inputStream;
try {
inputStream = new FileInputStream(file);
byte[] content = FileCopyUtils.copyToByteArray(inputStream);
String filename = "com-logs.tar";
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + filename);
responseHeaders.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream"
);
return new ResponseEntity<byte[]>(content, responseHeaders, HttpStatus.OK);
} catch (Exception e) {
logger.error("Error while processing log file for download", e);
}
} else {
logger.error("Failed to download logs");
}
return ResponseEntity.badRequest().build();
}
Код Angular.js на стороне клиента —
this._service.downloadLogs().subscribe(
success => {
var blb = new Blob([success], { 'type': "application/octet-stream" });
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blb, 'logs.tar');
}
else {
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blb);
link.download = "logs.tar";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
});
Новый Java-код на стороне сервера -
public void downloadLogs(HttpServletResponse resonse) {
File file = preferencesService.downloadLogs(id);
if (file != null) {
try {
resonse.setContentType("application/octet-stream");
resonse.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
BufferedInputStream inStrem = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream outStream = new BufferedOutputStream(resonse.getOutputStream());
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = inStrem.read(buffer)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
outStream.flush();
inStrem.close();
}
...
}