-1

我已经使用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();
4

2 回答 2

2

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

  • 您的程序遇到了一个文件,该文件正在加载到可用内存中。这将导致垃圾收集器超时工作以释放空间,并且很容易导致您的程序看起来被冻结。

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

几点建议:

  • 检查 CPU 使用率——你的程序真的在做什么吗?还是在某个地方陷入僵局?您的硬盘驱动器是否处于活动状态?

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

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

恐怕如果没有有关您的程序的更多信息,将很难提供更具体的答案...

于 2013-01-02T17:53:04.660 回答
0

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

准确告诉我问题出在哪里。

我怀疑问题出在硬盘驱动器的速度上。如果您有一个寻道时间为 8 ms 的 HDD;

  • 查找文件以读取 8 毫秒
  • 读取文件 4-12 毫秒
  • 找到文件写入 8 毫秒
  • 写入文件 4-12 毫秒
  • 更新文件系统日志 8 毫秒。

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

只需不到 50 美元,您就可以购买访问时间为 0.1 毫秒的 32 GB SSD。你可以花不多的钱买到双倍的尺寸。

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

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

看起来您可以做更多事情的唯一原因是操作系统在一定程度上缓存了读取和缓冲写入。当这些用尽时(在 Windows 上它们似乎相当快),您会受到驱动器速度的限制。

于 2013-01-02T17:33:20.227 回答