我们希望有一个 Java REST API 来从 Google Cloud Storage 返回文件作为附件。我能够使用以下方法让它工作。问题是文件必须本地下载到服务容器(我们部署在 Google Cloud Run 上),这在文件非常大的情况下会出现问题,并且通常可能是不好的做法。有没有办法以某种方式修改此代码以跳过本地文件的创建?
@GetMapping(path = "/file", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<InputStreamResource> getSpecificFile(@RequestParam String fileName,
@RequestParam String bucketName, @RequestParam String projectName) {
Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
Blob blob = storage.get(bucketName, fileName);
ReadChannel readChannel = blob.reader();
String outputFileName = tempFileDestination.concat("\\").concat(fileName);
try (FileOutputStream fileOutputStream = new FileOutputStream(outputFileName)) {
fileOutputStream.getChannel().transferFrom(readChannel, 0, Long.MAX_VALUE);
String contentType = Files.probeContentType(Paths.get(outputFileName));
FileInputStream fileInputStream = new FileInputStream(outputFileName);
return ResponseEntity.ok().contentType(MediaType.valueOf(contentType))
.header("Content-Disposition", "attachment; filename=" + fileName)
.body(new InputStreamResource(fileInputStream));
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.internalServerError().body(null);
} finally {
// delete the local file as cleanup
try {
Files.delete(Paths.get(outputFileName));
} catch (IOException e) {
e.printStackTrace();
}
}
}
嗯,我没花很长时间就明白了。我能够使其工作如下:
@GetMapping(path = "/file", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<InputStreamResource> getSpecificFile(@RequestParam String fileName, @RequestParam String bucketName, @RequestParam String projectName) {
Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
Blob blob = storage.get(bucketName, fileName);
ReadChannel readChannel = blob.reader();
try {
String contentType = Files.probeContentType(Paths.get(fileName));
InputStream inputStream = Channels.newInputStream(readChannel);
return ResponseEntity.ok().contentType(MediaType.valueOf(contentType))
.header("Content-Disposition", "attachment; filename=" + fileName)
.body(new InputStreamResource(inputStream));
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.internalServerError().body(null);
}
}
基本上将 InputStream 重定向到 readChannel 而不是文件。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)