Java Stream BufferedReader file stream

I am using Java 8 Streams to create stream from a csv file. I am using BufferedReader.lines(), I read the docs for BufferedReader.lines():

After execution of the terminal stream operation there are no guarantees that the reader will be at a specific position from which to read the next character or line.

public class Streamy {
    public static void main(String args[]) {
        Reader reader = null;
        BufferedReader breader = null;
        try {
            reader = new FileReader("refined.csv");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        breader = new BufferedReader(reader);
        long l1 = breader.lines().count();
        System.out.println("Line Count " + l1); // this works correctly

        long l2 = breader.lines().count();
        System.out.println("Line Count " + l2); // this gives 0
    }
}

It looks like after reading the file for first time, reader does not get to beginning of the file. What is the way around for this problem

Jon Skeet
people
quotationmark

It looks like after reading the file for first time, reader does not get to beginning of the file.

No - and I don't know why you would expect it to given the documentation you quoted. Basically, the lines() method doesn't "rewind" the reader before starting, and may not even be able to. (Imagine the BufferedReader wraps an InputStreamReader which wraps a network connection's InputStream - once you've read the data, it's gone.)

What is the way around for this problem

Two options:

  • Reopen the file and read it from scratch
  • Save the result of lines() to a List<String>, so that you're then not reading from the file at all the second time. For example:

    List<String> lines = breader.lines().collect(Collectors.toList());
    

As an aside, I'd strongly recommend using Files.newBufferedReader instead of FileReader - the latter always uses the platform default encoding, which isn't generally a good idea.

And for that matter, to load all the lines into a list, you can just use Files.readAllLines... or Files.lines if you want the lines as a stream rather than a list. (Note the caveats in the comments, however.)

people

See more on this question at Stackoverflow