简体   繁体   中英

Java - How to read a file twice using buffer reader or use stream twice

How to read file twice eihher using buffer reader or using stream twice ???

  • That I need manipulate large amounts of data in the code, so the performance needs to be considered.

Sample code 1 below, gives exception "stream closed" -

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

Sample code 2 below, gives exception "stream closed/being used" -

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

Please ignore the syntax, it's just a draft code. Kindly suggest.

In terms of use a stream is somewhat analogous to an iterator in that it can only be used once.

If you want to use the contents of the same stream again you need to create a new stream as you did the first.

As of Java 12, you can pass values of the same stream into two branches by using the Collectors.teeing() method.

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

You can also do this.

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

Now you can use ss1 and ss2 as two separate streams.

Here have an example below. You could use it to read as many times as you wish.

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);
}

reference

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

You cannot. A stream is just like its real-life watery counterpart. You can observe the water going under the bridge you're standing on, but you can't instruct the water to go back to the top of the hill so that you can observe it again.

Either have each consumers process each line before moving on to the next line, or if that is not possible then you will need to create your own "buffer" of the entire thing: ie store each line to Collection<String> , which the second (and third, and fourth...) consumer can iterate over. The potential problem with this is that it's a bigger memory overhead. The HTML of most websites is not likely to prove to be much of a problem in this regard.

Your last example can be trivially fixed by copying the list.

List ll = ss.collect();
List xx = new ArrayList(ll);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM