【问题标题】:Java Heap: out of memory when converting a file to byte array for return [duplicate]Java堆:将文件转换为字节数组以返回时内存不足[重复]
【发布时间】:2021-05-20 21:13:27
【问题描述】:

我正在尝试将已下载的文件转换为 byte[] 并返回。我可以转换而不会失败的最大大小约为 70mb,这是我的 ubuntu 实例上的可用内存量。需要与 RAM 相当的文件大小才能下载它是不现实的。

我已尝试将 BufferedInputStream 转换为 ByteArrayOutputStream,但它在开始写入时内存不足。在下面的代码中,它会在停止之前进入“开始缓冲写入”。

            FileInputStream fis = null;
            BufferedInputStream bis = null;
            byte[] bytes = null;
            byte[] buffer = new byte[1024];
            int count = 0;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            
            try
            {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                
                System.out.println("Starting buffered write");
                while((count=bis.read(buffer)) != -1)
                {
                    bos.write(buffer, 0, count);
                }
                System.out.println("Finished buffered write");
                
                //System.out.println("Trying copyLarge");
                //IOUtils.copyLarge(fis, bos);
                //System.out.println("Successful copyLarge");
                
                System.out.println("Starting stream to bytes");
                bytes = bos.toByteArray();
                System.out.println("Finished stream to bytes");
                
                fis.close();
                bis.close();
                bos.flush();
                bos.close();
            }

让我感到困惑的是,这种方法适用于大文件的上传功能没有问题。上传创建一个临时文件和一个输出流,然后将上传的文件输入流写入其中。是否有可能由于上传的临时文件在使用后没有被删除,它们正在耗尽我的实例内存?

【问题讨论】:

  • 您可以将大文件从网络写入磁盘或从磁盘写入网络,但如果您打算将整个文件保存在byte[] 中,那么您需要内存。不要创建将文件返回为byte[] 的方法,这是不好的设计(如果你真的需要它,可以使用Files.readAllBytes(Paths.get("/path/to/file")))。
  • 有道理,谢谢。是否可以将文件作为 ResponseEntity 返回而不将其转换为字节数组?我目前正在将其写入 byte[],创建一个 ByteArrayResource,并将其作为 ResponseEntity 的主体返回。
  • Streaming 永远是关键,所以当你不需要的时候不要把它们放在内存中。
  • 谢谢!将它们作为 ResourceStream 返回效果很好

标签: java amazon-s3 download upload


【解决方案1】:

正如 Kayaman 告诉我的,将文件加载为字节数组需要内存中文件的完整大小。将我的文件作为 InputStreamResource 返回以供下载解决了我没有字节数组的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 1970-01-01
    • 2014-06-25
    • 2019-05-20
    • 2013-04-07
    相关资源
    最近更新 更多