Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BufferReader unexpected output

I have this simple method:

private String read(String filePath) throws IOException {
    FileReader fileReader = new FileReader(filePath);
    BufferedReader bufferedReader = new BufferedReader(fileReader);
    String fileContent = "";
    StringBuilder stringBuilder = new StringBuilder(fileContent);

    while (bufferedReader.readLine() != null){
        System.out.println(bufferedReader.readLine());
        stringBuilder.append(bufferedReader.readLine());
    }
    return fileContent;
}

As you can see in line 8 I included print for debuging purposes I would like this method to return String from this txt file:

1a1
2b 2a
3c 3b 3a
4d 4cr 4bb4 4a
5e 5d 5c 5b 5ax
6f 6ea 6d 6ca 6bb 6a
7g 7f 7ea

for some reason output is like that:

2b 2a
5e 5d 5c 5b 5ax
null

Why it reads only second and fifth line? Where this null comes from? String returned on the end seems empty.

I would like to understand what is happening here. Thx :)

like image 695
michal w Avatar asked Jan 01 '23 12:01

michal w


2 Answers

This is because you use every third line in the while loop's null check, print every third line counting from two, and append every third line counting from three, like this:

1  null check
2  print
3  append
4  null check
5  print
6  append
7  null check
8  print
9  append
... and so on

You should save the line you read in a String variable, and use it inside the loop, as follows:

String line;
while ((line = bufferedReader.readLine()) != null){
    System.out.println(line);
    stringBuilder.append(line);
}

Now the loop header combines an assignment and a null check, and the variable assigned from readLine represents the last line read from the file.

like image 121
Sergey Kalinichenko Avatar answered Jan 04 '23 17:01

Sergey Kalinichenko


Each readLine() is reading an entirely new line, to analyze what's going on let's name each readLine() call.

while (bufferedReader.readLine() != null) {          // Read 1
    System.out.println(bufferedReader.readLine());   // Read 2
    stringBuilder.append(bufferedReader.readLine()); // Read 3
}

Now let's associate each readLine() with the line that it reads:

1a1                   // Read 1 while loop condition
2b 2a                 // Read 2 this is when we print it
3c 3b 3a              // Read 3 append to stringBuilder
4d 4cr 4bb4 4a        // Read 1 while loop condition
5e 5d 5c 5b 5ax       // Read 2 this is when we print it
6f 6ea 6d 6ca 6bb 6a  // Read 3 append to stringBuilder
7g 7f 7ea             // Read 1 while loop condition
                      // Read 2 this is when we print it (null)
                      // Read 3 append to stringBuilder

As you can see you're consuming a lot of lines, and you're only printing a few. Other's have pointed out great solutions to fix this already hence that's not in this answer.

like image 25
Mark Avatar answered Jan 04 '23 15:01

Mark