高效搜索和替换java中大量文件的程序

时间:2013-01-02 17:29:02

标签: java regex full-text-search performance

我使用正常表达式为使用 eclipse ide 的大量文件创建了一个搜索和替换程序。在这个程序中,我给出了要执行搜索和替换的目录名称(它也可能有子目录)。对于少量文件,它运行顺利,但对于有1000个文件的目录,挂起介于两者之间(即使在增加jvm内存大小之后)。 我已经使用BufferedReader逐行读取每个文件,并使用正则表达式匹配行中的模式,然后用其他文本替换它。 任何机构都可以向我建议可能的解决方案(算法,库,技巧,黑客)吗?

        BufferedReader br = new BufferedReader(new FileReader(fileName));
        BufferedWriter bw = new BufferedWriter(new FileWriter(changedFile));
        StringBuilder sb = new StringBuilder();
        for (String line = br.readLine(); line != null; line = br.readLine()) {
            sb.append(line).append("\n");
        }
        br.close();
        sb.trimToSize();
        String code = sb.toString();
        code = code.replaceAll("System", "PrintWriter");
        bw.write(code);
        bw.flush();
        bw.close();

2 个答案:

答案 0 :(得分:2)

您提供的代码段似乎(大部分)对我来说是正确的,因为它确实会将整个文件加载到内存中,执行替换并将其写回。我怀疑你的问题:

  • 您的程序遇到了一个边缘w.r.t的文件。被加载到可用的内存中。这将导致垃圾收集器超时工作以释放空间,并且很容易导致您的程序被冻结。

  • 您的目录递归代码在某处纠结,并且会反复阻塞或迭代相同的文件。

一些建议:

  • 检查CPU使用情况 - 您的程序实际上在做什么?或者它在某处陷入僵局?你的硬盘是否有效?

  • 让您的程序在处理之前打印每个文件名。它每次都停在特定文件上吗?它是否在同一组文件上循环?

  • 使用Eclipse调试器或JVM监视器(例如VisualVM)来检查您的程序。出现冻结时它在做什么?它的内存使用情况和GC活动是什么样的?

我担心如果没有关于你的程序的更多信息,提供更具体的答案将非常困难......

答案 1 :(得分:0)

我怀疑你的操作系统中的写缓冲区正在填满,它必须等待数据刷新到磁盘,除非你可以确定该程序由于其中的错误而挂起。使用调试器是一种测试方法或使用jstack进行堆栈跟踪的简单方法。

  

告诉我确切的问题在哪里。

我怀疑问题出在硬盘的速度上。如果您的硬盘驱动器的寻道时间为8毫秒;

  • 找到文件读取8毫秒
  • 读取文件4-12 ms
  • 找到要写入8 ms的文件
  • 将文件写入4-12 ms
  • 更新文件系统日志8毫秒。

总时间约为32 - 48毫秒,这意味着您每秒可以更新大约20 - 30个文件。

对于< $ 50,您可以购买32 GB SSD,访问时间为0.1 ms。你可以购买双倍大小的东西。

  • 找到文件读取0.1毫秒
  • 读取文件0.1 ms
  • 找到文件写入0.1毫秒
  • 将文件写入0.1 ms
  • 更新文件系统日志0.1 ms。

总时间可能为0.5毫秒,允许您每秒处理多达2000个文件。

它看起来你可以做更多的唯一原因是操作系统缓存读取和缓冲写入到一个点。当它们用尽时(它们在Windows上看起来相当快),你会受到驱动器速度的限制。