【发布时间】: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