繁体   English   中英

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

[英]Return file from Google Cloud Storage through REST API without downloading locally first

我们想要一个 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));
        log.info("Determined the contentType for file {} to be: {}", fileName, contentType);

        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 而不是文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM