Java 8 BufferedReader lines()方法打印不同的计数

Java 8 BufferedReader lines()方法打印不同的计数,java,lambda,bufferedreader,java-8,Java,Lambda,Bufferedreader,Java 8,我遇到了一个使用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 lin

我遇到了一个使用
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
?提前感谢。

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

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

的javadoc指定:

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


我理解这意味着不能保证它紧跟在从流返回的最后一行之后,但由于计数消耗了所有行,我非常确定它在末尾。回到读者的开头(通常)是不可能的

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

来自:

在执行终端流操作之后,没有 保证读卡器将位于一个特定的位置 读取下一个字符或行

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

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

因此,在执行
br.lines().count()
语句后,无法保证指针的位置


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

@BlackPanther再次使用相同的数据。是的,不幸的是,它没有解释上述行为;实际上,流已经前进到读取下一行的位置。只是1)它没有更多的线路,2)它没有关闭。请注意,它说的是“一个位置”而不是“开始位置”,我认为这是因为在阅读所有内容之前,线路上的操作可能已经结束。但这不是否决答案的理由。从javadoc的引用中可以清楚地推断出,第一次调用消耗了数据,不能再使用。“在执行终端操作后,流管道被视为已消耗,并且无法再使用”从“返回到读取器的开头(通常)是不可能的”。如果您有足够大的缓冲区,可以使用
mark()
,标记:P@owlstead因此,我通常我认为可以安全地假设
BufferedReader
(或任何读取器或inputstream)永远不会返回到起始位置(除非使用
标记(…)
重置()
(如果支持)明确请求);该警告表示,该位置可能不是您从流中消耗的最后一行中所期望的位置(例如,紧跟在该行之后)。@BlackPanther“因此,在执行br.lines()语句后,指针的位置没有任何保证。”请注意,count()是终端操作,而不是line()。作为一般规则,不要期望流在终端操作之后可以重用。