通过 REST API 从 Google Cloud Storage 返回文件,无需先下载到本地

2024-01-01

我们希望有一个 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(使用前将#替换为@)

通过 REST API 从 Google Cloud Storage 返回文件,无需先下载到本地 的相关文章

随机推荐