Java中的InputStream存在内存问题

时间:2011-01-28 09:44:20

标签: java inputstream

我需要将文件读入Bytes数组。整个文件需要读入数组。问题是我收到OutOfMemory错误,因为文件太大。增加-XmX似乎没有任何影响。以下是代码段:

InputStream in = new FileInputStream(file);
long length = file.length();                        
byte[] out = new byte[(int)length]; 
// Process the byte array

在字节数组实例期间出现问题。这个问题的内存密集型解决方法是否较少?

4 个答案:

答案 0 :(得分:3)

您需要拥有比使用此方法所需的最大文件更多的可用内存。鉴于24 GB的成本低于2K英镑的机器,这并不像以前那么愚蠢。实际上,在某些情况下,字节[]的2GB限制更令人头疼。

但是,读取InputStream的常用方法是一次读取一个8KB的块。这样你只需要有超过8KB的免费。

顺便说一句:您可以使用-mx1g代替您正在使用的选项。

答案 1 :(得分:2)

不,如果你的文件太大而无法放入内存,那么它太大而无法放入内存。

更好的解决方案是尝试将流作为流处理,而不是将整个内容加载到内存中。在不知道你想要实现什么样的处理的情况下,我们无法确定这是否可行。

例如,如果您只是尝试计算文件的安全哈希值,那么您应该能够在不加载大量数据的情况下执行此操作 - 但如果您的处理需要随机访问数据,那么可能需要使用RandomAccessFile代替。

答案 2 :(得分:1)

workarround将是,而不是将整个文件加载到RAM中。实际上你不能为大文件做这件事,因为你必须在一个和平时分配大量的内存,这可能不起作用。

问题是:你真的需要内存中的整个文件吗?

修改

InputStream in = new FileInputStream(file);
long length = file.length();     
// At this point a warning should appear, because the code would
// not work for files larger than Integer.MAX_VALUE                   
byte[] out = new byte[(int)length]; 

答案 3 :(得分:0)

如何使用内存映射文件:FileChannel

来自http://www.java-tips.org/java-se-tips/java.nio/how-to-create-a-memory-mapped-file-3.html

try {
    File file = new File("filename");

    // Create a read-only memory-mapped file
    FileChannel roChannel = 
      new RandomAccessFile(file, "r").getChannel();

    ByteBuffer readonlybuffer = 
      roChannel.map(FileChannel.MapMode.READ_ONLY, 
0, (int)roChannel.size());

    // Create a read-write memory-mapped file
    FileChannel rwChannel = 
      new RandomAccessFile(file, "rw").getChannel();

    ByteBuffer writeonlybuffer= 
      rwChannel.map(FileChannel.MapMode.READ_WRITE, 
  0, (int)rwChannel.size());

    // Create a private (copy-on-write) memory-mapped file.
    // Any write to this channel results in a private 
    // copy of the data.
    FileChannel pvChannel = 
      new RandomAccessFile(file, "rw").getChannel();

    ByteBuffer privatebuffer = 
      roChannel.map(FileChannel.MapMode.READ_WRITE, 
  0, (int)rwChannel.size());

} catch (IOException e) {
}