我需要将文件读入Bytes数组。整个文件需要读入数组。问题是我收到OutOfMemory错误,因为文件太大。增加-XmX似乎没有任何影响。以下是代码段:
InputStream in = new FileInputStream(file);
long length = file.length();
byte[] out = new byte[(int)length];
// Process the byte array
在字节数组实例期间出现问题。这个问题的内存密集型解决方法是否较少?
答案 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) {
}