0

如何使用缓冲区读取器或使用流两次读取文件?

  • 我需要在代码中操作大量数据,因此需要考虑性能。

下面的示例代码 1 给出异常“流已关闭”-

Url url = 'www.google.com'
InputStream in = url.openStream();
BufferReader br = new BufferReader(in);

Stream<String> ss = br.lines; // read all the lines

List ll = ss.collect();
br.close();
BufferReader br = new BufferReader(in); //exception occurs

下面的示例代码 2 给出异常“流已关闭/正在使用”-

Url url = 'www.google.com'
InputStream in = url.openStream();
BufferReader br = new BufferReader(in);

Supplier<Stream<String>> ss = br.lines; // read all the lines

List ll = ss.collect();
List xx = ss.collect();. // Exception occurs

请忽略语法,这只是一个草稿代码。请建议。

4

3 回答 3

0

在使用方面,astream有点类似于 a iterator,因为它只能使用一次。

如果您想再次使用同一流的内容,您需要像第一次那样创建一个新流。

从 Java 12 开始,您可以使用该Collectors.teeing()方法将同一流的值传递到两个分支。

List.stream().collect(Collectors.teeing(
                Collector1, // do something with the stream
                Collector2, // do something else with the stream
                BiFunction, use to merge results)

你也可以这样做。

Supplier<Stream<String>> ss1 = br.lines; // read all the lines
Supplier<Stream<String>> ss2 = br.lines; // read all the lines

现在您可以将ss1andss2用作两个单独的流。

于 2020-01-16T18:44:03.877 回答
0

下面有一个例子。您可以根据需要使用它多次阅读。

BufferedReader br = new BufferedReader(new FileReader( "users/desktop/xxx.txt" ));
String strLine;
List<String> ans= new ArrayList<String>();

// Read rows
while ((strLine = br.readLine()) != null) {
    System.out.println(strLine);
    ans.add(strLine);
}

// Read again
for (String result: ans) {
    System.out.println(result);
}

参考

https://www.dreamincode.net/forums/topic/272652-reading-from-same-file-twice/

于 2020-01-16T18:45:52.377 回答
0

你不能。溪流就像现实生活中的水一样。你可以观察你所站立的桥下的水流,但你不能指示水流回到山顶,这样你就可以再次观察它。

要么让每个消费者在进入下一行之前处理每一行,或者如果这不可能,那么您将需要创建自己的整个事物的“缓冲区”:即将每一行存储到Collection<String>第二个(和第三个,第四……)消费者可以迭代。这样做的潜在问题是它的内存开销更大。大多数网站的 HTML 在这方面不太可能被证明是一个很大的问题。

您的最后一个示例可以通过复制列表来轻松修复。

List ll = ss.collect();
List xx = new ArrayList(ll);
于 2020-01-16T18:47:10.010 回答