Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding how BufferedReader works in Java

Very basic question on how BufferedReader works. Given the string/phrase, I want to find and print it from the file with a lot of text in it.

using BufferedReader in Java I did some research on this topic and that was the closest result. Not quite addressing my problem though.

So with this information, why does the following code terminate?

public class MainApp {

String line = null;
String phrase = "eye";

try {
    File file = new File("text.txt");
    FileReader fr = new FileReader(file);
    BufferedReader br = new BufferedReader(fr);

    while((line = br.readLine()) != null) {
        if (line.equals(phrase) {
            System.out.println(line);
           }
        }

    br.close();

} catch (Exception e) {
   e.printStackTrace();
  }
 }
}

My understanding of how this block should work:

  • The while loop goes through each line of text until the condition is no longer true
  • Each line is stored in the BufferedReader
  • Loop is working until the condition of if (line.equals(phrase) is met.
  • Prints found phrase.

Why I think it might not work:

  • readlines are not stored as strings in the BufferedReader (therefore they can't be compared)

  • faulty logic (most likely the if statement)

For the sake of simplicity, let's assume that "text.txt" is filled with very long lore ipsum with a single "eye" word put somewhere in the middle of it.

Where exactly is the problem? (Don't provide the entire code solution if possible, I'd love to do the coding part myself for the sake of practice).

like image 895
Lotix Avatar asked Mar 08 '15 17:03

Lotix


4 Answers

Your code should work. The BufferedReader Class just read buffers of data from the stream. It just means it does not read byte by byte from the file (which would take an eternity to execute).

What the BufferedReader Class will do is read a buffer of bytes from the file (1024 bytes for instance). It will look for a line separator ("\n") in the buffer. If not found, the bytes will be appended in a StringBuilder object and the next buffer will be fetched. This will happen until a line separator is found in the buffer. All bytes in the buffer up until the line separator will be appended to the StringBuilder object, and finally the String will be returned to you.

Edit: depending on implementation, the line separator might or might not be included in the String. Other people pointed out contains(), however, it would be a lot slower. If you want to find a specific line, do it with equals() (Add the line separator in the phrase String). If you want to find a specific phrase within a line, then contains() is the way to go.

like image 133
sturcotte06 Avatar answered Oct 02 '22 13:10

sturcotte06


you need to use the line.contains method, not the line.equals which you are currently using

if (line.contains(phrase)) { 

so it is what you're saying "faulty logic (most likely the if statement)"

then you can print the line (or whatever you want to do)

System.out.println(s);

if the line is the following :

Lorem ipsum dolor sit amet, **eye** consectetur adipiscing elit.

it will not match although it contains the eye which you want to capture.. so change the if as I mentioned and you are good to go

like image 25
adrCoder Avatar answered Oct 02 '22 15:10

adrCoder


Your understanding of how this block should work:

  • The while loop goes through each line of text until the condition is no longer true

Correct :-) .

  • Each line is stored in the BufferedReader

Not correct. The bufferedReader does not store any data, it just reads it (Thats why it's called bufferedReader). When you call br.readLine() it will give you a String with the contents of the line, but it will not store anything itself. In your case, each line is stored in the line variable, which is overwritten each time the loop runs.

  • Loop is working until the condition of if (line.equals(phrase) is met.

Not correct. The loop will continue working even if the condition is met. If you want the loop to stop, you need to insert a break statement. In your case, when the condition is met, it will print the whole line, and the loop will continue. In your case the statement will probably never be met, because the if (line.equals(phrase) will probably never be true.

  • Prints found phrase.

Possibly, if the whole line equals the phrase. If the phrase is surrounded by other words, the condition (line.equals(phrase) will not be true.

Why you think it might not work:

  • readlines are not stored as strings in the BufferedReader (therefore they can't be compared)

As I said above, nothing is stored inside the BufferedReader . You are storing each individual line in the line variable. Then you are comparing with the line variable.

  • faulty logic (most likely the if statement)

Yes. The condition in the if statement is wrong, since it checks if the whole line matches the wanted phrase. Also, the loop will continue running, even if the phrase is found.

For the sake of simplicity, let's assume that "text.txt" is filled with very long lore ipsum with a single "eye" word put somewhere in the middle of it.

In this case, your code will probably not print anything.

Where exactly is the problem? (Don't provide the entire code solution if possible, I'd love to do the coding part myself for the sake of practice)

The problem is in the condition for the loop. Hover here to see how it should be:

if (line.contains(phrase))

Also, there is no break statement in the loop, so it will print the phrase multiple times, if it exists in the file. (And if the condition for the loop is fixed!)

like image 42
JonasCz Avatar answered Oct 02 '22 13:10

JonasCz


When you read a line it will also contain all other data on the line

some words eye some other words

To correctly find if that line contains 'eye' you should call contains() instead of equals()

if (line.contains(phrase))
like image 29
Andreas Wederbrand Avatar answered Oct 02 '22 15:10

Andreas Wederbrand