将文件下载为 ByteArray 与资源,哪个更好,占用内存更少

问题描述 投票:0回答:1

我们使用 byte[] 作为返回类型的下载之一

@PostMapping("/downloadReport")
    public ResponseEntity<byte[]> downlodReport(@RequestBody Request request) {
        byte[] fileContents = someByteContent;
        ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
                .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                .body(fileContents)
        
    }

我们在下载文件时看到超过 100% 的 CPU,当我在 google 上搜索发现以 Resource 作为返回类型的大多数示例时,当我们以 byte[] 返回时,文件是否加载到内存中,而 byte[] 在下载时会消耗内存文件?如果我使用 Resource 作为返回类型并使用 InputStreamResource resource = new InputStreamResource(new FileInputStream(file)); ,在内存使用方面是否会更好?

任何建议都表示赞赏

java spring-boot memory cpu-usage
1个回答
0
投票
当你创建一个 byte[] 时,你就是在告诉 Java“在内存中创建一个字节列表,并返回指向这些字节的指针。”具体来说,对象引用在堆上分配,指针存储在堆栈中。

因此,当你使用byte[]来存储文件时,需要将文件的全部内容加载到内存中。

当您返回 byte[] 时,它还会从内存中加载整个内容。我想说,在大多数用例中,这不是问题,但这很大程度上取决于这些文件的用途和大小。

如果文件通常很大,我会尝试这样的方法:

InputStreamResource inputStreamResource = new InputStreamResource(inputStream); httpHeaders.setContentLength(contentLengthOfStream); return new ResponseEntity(inputStreamResource, httpHeaders, HttpStatus.OK);


java - return-a-stream-with-spring-mvcs-responsentity.

但我认为需要进行一些测试来确定在什么时候返回 byte[] 是更好的以及在什么时候返回流是更好的。我会做一些测试并回复您。

现在,您可能想要探索的另一个选项是不将文件存储在数据库中,生成它们并将它们存储在文件系统上,然后仅在视图中返回一个转发:/请求以将用户重定向到文件,这样,您将向 Web 服务器提供文件的责任卸下来,这通常更适合高效处理静态资源。

© www.soinside.com 2019 - 2024. All rights reserved.