我真的有麻烦了:我想使用 FileChannel
和 MappedByteBuffer
读取超过几 GB 的巨大文件 - 我找到的所有文档都暗示映射相当简单使用 FileChannel.map()
方法的文件。
当然有一个 2GB 的限制,因为所有 Buffer 方法都使用 int 来表示位置、限制和容量——但是系统隐含的限制低于这个值呢?
实际上,我遇到了很多关于 OutOfMemoryException
的问题!并且根本没有真正定义限制的文档!
那么 - 我如何才能将一个符合 int-limit 的文件安全地映射到一个或多个 MappedByteBuffer
而不会出现异常?
我可以在尝试 FileChannel.map()
之前询问系统我可以安全地映射文件的哪一部分吗?如何?
为什么关于这个功能的文档这么少??
最佳答案
我可以提供一些工作代码。这是否能解决您的问题很难说。这会在文件中搜索 Hunter
识别的模式。
见优秀文章Java tip: How to read files quickly用于原始研究(不是我的)。
// 4k buffer size.
static final int SIZE = 4 * 1024;
static byte[] buffer = new byte[SIZE];
// Fastest because a FileInputStream has an associated channel.
private static void ScanDataFile(Hunter p, FileInputStream f) throws FileNotFoundException, IOException {
// Use a mapped and buffered stream for best speed.
// See: http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly
FileChannel ch = f.getChannel();
long red = 0L;
do {
long read = Math.min(Integer.MAX_VALUE, ch.size() - red);
MappedByteBuffer mb = ch.map(FileChannel.MapMode.READ_ONLY, red, read);
int nGet;
while (mb.hasRemaining() && p.ok()) {
nGet = Math.min(mb.remaining(), SIZE);
mb.get(buffer, 0, nGet);
for (int i = 0; i < nGet && p.ok(); i++) {
p.check(buffer[i]);
}
}
red += read;
} while (red < ch.size() && p.ok());
// Finish off.
p.close();
ch.close();
f.close();
}
关于Java NIO MappedByteBuffer 内存溢出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12531984/