在Java中打开大文件非常缓慢。

13

我有一个大小为12GB的文件,需要使用Java从中提取小数据块(每个几千字节)。一旦文件打开,查找和读取数据非常快,但是打开文件本身需要花费很长的时间-大约90秒。是否有方法可以加速Java中的打开文件操作?

为了澄清,我尝试了以下选项来打开和读取文件:

new FileInputStream(file); 
new RandomAccessFile(file, "r");
Files.newByteChannel(path, StandardOpenOption.READ);

每一个都产生了类似的结果。


@Blacklight 跳过、设置位置等操作运行良好且非常快速。90% 的时间都花费在第一次跳过之前打开文件上。 - Little Bobby Tables
@Vash 上述任何一个构造函数在打开一个12GB的文件时大约需要90秒钟。调用构造函数本身会停顿。 - Little Bobby Tables
1
@小博比表,我快速查看了FileChannelImpl。它似乎延迟了本地调用。因此,也许性能问题仍然存在,只是发生的时间稍晚了?您是否尝试在不同的操作系统上打开文件?也许病毒扫描器正在拦截读取以临时扫描文件? - Stefan
@LittleBobbyTables,祝你考试好运。我期待着结果。 - Damian Leszczyński - Vash
1
@AkselWillgert 只需在 Windows 操作系统上运行上述任何一个构造函数,对一个非常大的文件(例如我的情况是 12GB)进行时间测量。 - Little Bobby Tables
显示剩余24条评论
2个回答

10

评论中指出,问题具体在于Java的打开文件操作会触发运行病毒扫描的操作系统操作,解决方案是将Java添加到可信进程列表中。


澄清一下 - 要么将Java添加为受信任的进程,要么排除该大文件免受即时病毒扫描,或进行任何其他设置以使病毒扫描器远离。谢谢,Stefan! - Little Bobby Tables

1
你遇到的问题大多是由你使用的JNI引起的。
因为你的代码在构造函数期间等待FileInputSream(String)。它验证传递路径的存在并调用一个方法private native void open(String)
然后,FileInputSream#open(String)的OpenJDK实现看起来像:
    JNIEXPORT void JNICALL
    Java_java_io_FileInputStream_open(JNIEnv *env, jobject this, jstring path) {
        fileOpen(env, this, path, fis_fd, O_RDONLY);
    }

这将带领我们到io_util_md.c和方法 < p > < code > jlong winFileHandleOpen(JNIEnv *env,jstring path,int flags)

您可以在那里分析代码。


此时您有多种选择。

  • 检查不同的JDK版本
  • 编写C代码,创建一个JNI方法。
  • 检查不同的文件系统。

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