【问题标题】:Java iteration reading & parsingJava迭代器读取和解析
【发布时间】:2012-07-01 22:11:33
【问题描述】:

我有一个正在读取字符串的日志文件

public static String read (String path) throws IOException {
   StringBuilder sb = new StringBuilder();
   FileInputStream fs = new FileInputStream(path);
   InputStream in = new BufferedInputStream(fs);

   int r;
   while ((r = in.read()) != -1) {
       sb.append((char)r);
   }

   fs.close();
   in.close();

   return sb.toString();
}

然后我有一个解析器可以遍历整个字符串一次

void parse () {
   String con = read("log.txt");
   for (int i = 0; i < con.length; i++) {
       /* parsing action */
   }
}

这极大地浪费了 CPU 周期。我遍历Read 中的所有内容。然后我遍历Parse 中的所有内容。我可以将/* parsing action */ 放在Read 方法中的while 循环下,这样可以找到但我不想到处复制相同的代码。

如何在一次迭代中解析文件的内容,并且仍然有单独的解析和读取方法?

在 C# 中,我知道有某种 yield return 的东西,但我被 Java 锁定了。

我在 Java 中有哪些选择?

【问题讨论】:

  • 您是否有理由在阅读该行后不立即执行此操作,据我了解,我们可以在阅读行后立即进行模式匹配,还是我遗漏了什么?
  • 如果您真的是这样阅读文本文件的,那么您需要解决的问题比内存和 CPU 使用率更重要。
  • 您正在读取字节而不是字符,每个字节都被读取为一个 int,并且这个 int 的字符串表示被附加到一个 StringBuilder。如果您的文件包含 ASCII 格式的 ABC,则您的字符串将为“656667”。而且我什至没有提到您没有关闭您的流,并且您不尊重 Java 命名约定。

标签: java performance parsing iterator


【解决方案1】:

这极大地浪费了 CPU 周期。我遍历 Read 中的所有内容。然后我遍历 Parse 中的所有内容。我可以将 /* 解析操作 */ 放在 Read 方法中的 while 循环下,这样可以找到,但我不想到处复制相同的代码。

这比大量浪费 CPU 周期更糟糕。如您的代码所示,如​​果您只打算使用一次并且每次向前看一个字符,那么将整个文件读入字符串是一种巨大的内存浪费。如果你的文件很大,你会耗尽内存。

您应该在阅读时进行解析,并且永远不要一次将整个文件加载到内存中。

如果需要从多个位置调用解析操作,请将其设为函数并调用它,而不是到处复制相同的代码。复制单行函数调用就可以了。

【讨论】:

  • 我可能最终会这样做,但是 Java 中是否有类似 yield return 的东西,或者我应该忘记它吗?
  • 这个related question 可能有用。
猜你喜欢
  • 1970-01-01
  • 2016-04-18
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 2012-04-18
  • 2012-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多