使用BufferedOutputStream写入大文件

5

我正在尝试使用BufferedInputStreamBufferedOutputStream读写大于100 MB的大文件。但是我遇到了堆内存问题和OOM异常。
代码如下:

BufferedInputStream buffIn = new BufferedInputStream(iStream);
/** iStream is the InputStream object  **/

BufferedOutputStream buffOut=new BufferedOutputStream(new FileOutputStream(file));
byte []arr = new byte [1024 * 1024];
int available  = -1;
while((available = buffIn.read(arr)) > 0) {   
    buffOut.write(arr, 0, available); 
}      
buffOut.flush();
buffOut.close();        

我的问题是当我们使用 BufferedOutputStreeam 时,它是否会一直占用内存直到整个文件写完?
使用 BufferedOutputStream 写入大文件的最佳方法是什么?


它会缓冲直到你清空它。在while循环中清空它。 - jcomeau_ictx
2
@jcomeau_ictx - 不,BufferedOutputStream在你刷新它之前不会缓冲,它有一个固定的内部缓冲区大小。 - jtahlborn
喝酒时不应该发帖。对此感到抱歉。 - jcomeau_ictx
1
@HunterMcMillen 在循环内部刷新完全否定了使用BufferedOutputStream的意义,并且它对内存使用不会产生任何影响。 - user207421
可能是重复的问题:什么是OutOfMemoryError,如何调试和修复它? - Raedwald
这个单独的兆字节引起OOM的可能性不大。此外,当您使用如此大的数组时,BufferedInputStreamBufferedOutputStream都不太可能产生任何影响。它们所做的最好的事情是在数组很大时避免性能下降。它们未使用的8kiB自有字节数组也不太可能造成影响。 - Holger
1个回答

5

您提供的代码没有问题。您遇到的内存问题必须是由其他原因导致的。缓冲流有一个固定的内存使用限制。

当然,确定引起 OOME 的原因最简单的方法是让 OOME 生成堆转储,然后在内存分析器中检查该堆转储。


这是正确的。但是,代码存在问题,buffOut.write()可能会写入比您要求写入的字节数更少的字节,在这种情况下,您需要继续编写,直到您编写了所有可用的字节。 - BillRobertson42
1
@Bill - 不,那不是真的。write()总是写入所有字节(它没有返回值)。 - jtahlborn
你正在同时在许多线程中运行此代码吗?很难看出这是你内存不足错误的源头。 - Paul Jowett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接