【问题标题】:Java 8 BufferedReader lines() method prints different count numberJava 8 BufferedReader lines() 方法打印不同的计数
【发布时间】:2014-06-27 03:55:33
【问题描述】:

我遇到了使用BufferedReader 的lines() 方法计算行号的问题。以下是test.txt文件的内容。

1 Career
2 Filmography
3 Awards
4 References
5 External

这里是计算两次行号的源代码。

  BufferedReader br=new BufferedReader(new FileReader(new File("test.txt")));
  long lineNo=br.lines().count();
  long lineNo2=br.lines().count();

  System.out.println(lineNo); // 5
  System.out.println(lineNo2);// 0

在这里,我有疑问为什么lineNo2 的第二行打印0 而不是5?提前致谢。

【问题讨论】:

  • 作为一般规则,不要期望 Stream 在终端操作后可重用。

标签: java lambda bufferedreader java-8


【解决方案1】:

java 8 API 指定here

在终端流操作执行后,不能保证阅读器将处于读取下一个字符或行的特定位置。

所以在你执行br.lines().count() 语句之后,指针的位置就无法保证了。

lines().count() 调用会消耗文件中的数据,并且在再次调用时不会关闭流。它不能通过调用br.lines().count() 再次使用相同的数据。

【讨论】:

  • 我认为可以安全地假设BufferedReader(或任何阅读器或输入流)永远不会回到起始位置(除非使用mark(..)reset() 明确要求,如果支持的);警告表明该位置可能不是您从流中消耗的最后一行所期望的位置(例如,紧随该行之后)。
  • @BlackPanther “因此,在您执行 br.lines() 语句后,指针的位置无法保证。”请注意,count() 是终端操作,而不是 lines()。
【解决方案2】:

来自Javadoc

终端流操作执行后没有 保证读者将处于特定位置 读取下一个字符或行。

count() 是终端操作。因此,在第一次count()-call 之后,读者的位置是未指定的。

【讨论】:

  • @BlackPanther 是的,不幸的是它没有解释上述行为;实际上,流已经前进到读出下一行的位置。只是 1)它没有更多的行和 2)它还没有关闭。请注意,它说的是“一个位置”而不是“起始位置”,我认为这个注释是因为行上的操作可能在读取所有内容之前就已经结束。
  • 但这不是拒绝答案的理由。从javadoc的引用中可以清楚地推断出,第一次调用消耗了数据,不能再使用了。来自http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps的“终端操作执行后,流管道被认为已消耗,不能再使用”
【解决方案3】:

BufferedReader.lines() 方法返回一个流。访问流(例如,当您对其执行count() 时)将从缓冲区读取行,将BufferedReader 中的当前位置向前移动。

当您执行count() 时,会读取整个流,因此BufferedReader() 将 - 可能 - 在最后。第二次调用lines() 将返回一个不会读取任何行的流,因为读取器已经在其数据的末尾。

BufferedReader.lines() 的 javadoc 指定:

在执行终端流操作后,不能保证阅读器将位于读取下一个字符或行的特定位置。

我读到这意味着不能保证它立即在从流返回的最后一行之后,但是由于计数消耗了所有行,我很确定它在最后。回到阅读器的开头(通常)是不可能的。

如果您需要对来自BufferedReader.lines() 的数据执行多项操作,您要么需要处理一次流式传输,要么需要将数据收集到临时存储中。但请注意,执行诸如行数(或收集)之类的终端操作可能永远不会完成(例如,如果 BufferedReader 来自无限源)。

【讨论】:

  • “回到阅读器的开头(通常)是不可能的。”。如果你有足够大的缓冲区,你可以使用mark(), Mark :P
  • @owlstead 因此我的通常 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
  • 1970-01-01
相关资源
最近更新 更多