【问题标题】:How to read lines from line-number n to line-number m of a file?如何从文件的第 n 行到第 m 行读取行?
【发布时间】:2015-08-26 19:32:52
【问题描述】:

有没有一种方法可以从文件中读取第 n 行到第 m 行?

换句话说,我有一个包含超过 100k 条目的文件。我想一次加载 10k 行,处理它们,然后加载接下来的 10k 行,以便在有限的内存资源下运行。有没有办法做到这一点?

【问题讨论】:

  • 为什么不直接使用BufferedReader
  • 如果您使用的是readLine,那么您已经在使用BufferedReader,对吧?
  • 使用LineNumberReader,这是一个支持行号的BufferedReader
  • @Jean Logeart 是的,我已经在使用 BufferedReader ,但是要获取第二批,我最终从文件的开头开始并跳过所有已经获取的行。这是一项成本高昂的操作,而且当批量较小且总行数过多时,这会在时间上产生大量开销。有什么办法可以避免这种情况。
  • @Andreas :你能给我一个例子,比如我如何使用 LineNumberReader 和 BufferedReader 从第 n 行获取行到第 m 行?我可以使用 LineNumberReader 去一行。您能否告诉我如何使用 BufferedReader 从该行中获取行而不跳过第 n 行之前的所有行?

标签: java file readline


【解决方案1】:

您不能从任意行开始阅读,但这不是您在问题的第二部分中所说的。如果可以为整个过程保留资源,您想要的是以下内容:

int batchSize = 10000;
try (BufferedReader br = Files.newBufferedReader(file.toPath())) {
    boolean eof = false;
    while (!eof) {
        List<String> batch = new ArrayList<>(batchSize);
        for (int i=0 ; i<batchSize ; i++) {
            String line = br.readLine();
            if (eof = line == null) break;
            batch.add(line);
        }
        processBatch(batch);
    }
}

如果您想尽快释放资源,最好让 生产者 将文件按 10 000 行批量拆分,而 消费者 按顺序处理它们。这可以通过两个线程和一个BlockingQueue&lt;File&gt; 轻松实现。

【讨论】:

  • 嗨,第一批可以很容易地获取,但我最终会跳过已经获取的批次中的所有行来获取下一批。这会导致时间延迟。我实际上是在尝试一次从文件中分批 10k 行获取所有行。
  • @Dici 我发现最好用一个额外的括号来澄清(eof = line == null)(eof = (line == null))
  • @Dici 内联分配通常不好,所以也许if (line == null) { eof = true; break; } 更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
  • 2022-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-14
相关资源
最近更新 更多