In this article, we will understand what is BufferedReader class in java, when it should be used and how it is used to read a file or user input with examples.

What is BufferedReader
BufferedReader is a class in java.io package and is used for reading character based input. This means that it can be used read text files or user input from keyboard.
This is different from stream based classes such as InputStream or FileInputStream, which read binary files such as images, audio or binary files.

BufferedReader is a child class of java.io.Reader, which is a parent class for all the reader classes that read or produce character based data such as FileReader, StringReader, InputStreamReader etc.

Default buffer size of BufferedReader is 8192.

BufferedReader class reads the characters into a buffer. From this buffer, the characters are read into the application or where they are required.
If the buffer is not present, then it would read directly from the source, which is a costly and slow operation. Thus, BufferedReader is faster as compared to InputStream or FileReader.
Initializing BufferedReader
BufferedReader wraps around a Reader such as a FileReader or InputStreamReader. This is evident from its constructors shown below

public BufferedReader(Reader in) { }

This constructor accepts an object of type java.io.Reader.

Second constructor also accepts a buffer size(in bytes) as second argument as below

public BufferedReader(Reader in, int sz) { }

This is called Decorator pattern where one object wraps another one. It is this reader object, which actually reads the characters from the source into the buffer as shown below.
BufferedReader object

BufferedReader methods
Following are the important methods of BufferedReader class.
1. read()
This method is used to read a single character. Character is returned as an integer and it needs to be cast to a char as shown in the example below.

BufferedReader buffReader = new BufferedReader(new FileReader("D:/names.txt"));
// read single character
System.out.println((char)buffReader.read());

read() returns -1 if there is no character to read.

2. read(char buf[], int offset, int len )
This method reads characters into an array. offset means the number of characters after which it starts storing characters.
len is the maximum number of characters that are read.

3. readLine()
This method reads an entire line and returns it as a string. This method is commonly used to read a file since it is faster.
It considers a line to be terminated by new line character(‘\n’), carriage return(‘\r’) or when end of file is reached.

4. skip()
As the name states, skip() method skips the reading of certain characters. skip() accepts the number of characters that you want the BufferedReader to skip.

5. mark()
mark() method of BufferedReader is used to remember the position of reader. Thus, if you want to read some text and then come back again to read the same, then this method should be used along with reset().
mark() accepts a long value which represents the number of characters that should be read after marking.
If the argument to mark() is 0, then you get an IOException stating mark invalid. So, this value should be greater than 0.

6. reset()
reset() method brings back the reader to the most recent marked position so that you can read the text again. Example of mark() and reset() is given below.

try(BufferedReader breader = new BufferedReader(
  new FileReader("D:/names.txt"))) {
   int i = 0;
   // read first five chars
   while(i <= 5) {
      System.out.print((char)breader.read());
      i++;
   }
   // add line break
   System.out.println();
   // place mark at 6th position
   breader.mark(1);
   i = 0; 
   // read next five chars
   while(i <= 5) { 
      System.out.print((char)breader.read()); i++; 
   }
   // reset to sixth character
   breader.reset();
   i = 0;
   // line break
   System.out.println();
   // read next five chars
   while(i <= 10) {
      System.out.print((char)breader.read());
      i++;
   }
} catch(IOException e) {
   e.printStackTrace();
}

Output of this code is

Alexa
Josep
Josep

Notice that after reading the first five characters, we mark the position of reader. Then, the next five characters are read and reset() is called.
Calling reset() moves the reader back to the same position at which mark() was called. This is evident from the output, since the next 5 characters are the same as the previous 5 characters.
Calling reset() without calling mark() will result in an exception Stream not marked.

7. close()
Calling this method closes the reader. Once closed, the reader can not be used again.

Read file line by line example
Below is an example to read a text file line by line with BufferedReader class using its readLine() method.

BufferedReader breader = null;
try {
   breader = new BufferedReader(
        new FileReader("D:/names.txt"));
   String line = null;
   while((line = breader.readLine()) != null) {
     System.out.println(line);
   }
} catch(IOException e) {
   e.printStackTrace();
} finally {
   if(breader != null) {
      breader.close();
   }
}

readLine() returns null where there is nothing left to read. Thus, in order to read the file completely, a loop is used, which keeps on reading till the return value from readLine() is null.
It is a good practice to close the buffered reader after use. Since finally block is always executed, it should be closed inside finally.

Starting java 7, BufferedReader can be defined inside try-with-resources block. With this block, BufferedReader can be initialized after try between parenthesis as shown below.

try(BufferedReader breader = new BufferedReader(
  new FileReader("D:/names.txt"))) {
   String line = null; 
   while((line = breader.readLine()) != null) { 
      System.out.println();
   }
} catch(IOException e) {
   e.printStackTrace();
}

Benefit of using try-with-resources is that you do not need to explicitly close BufferedReader and it is closed automatically, once reading is finished.

Reading user input with BufferedReader
BufferedReader can also be used to read user input from keyboard. java.lang.System class contains a field in, which is of the type java.io.InputStream and is connected to the keyboard and reads input as bytes.

java.io.InputStreamReader wraps around System.in and its read() method converts bytes read by System.in into characters.
read() method reads a single character. For efficiently reading user input, BufferedReader is used.

BufferedReader wraps around InputStreamReader and its readLine() method can read user input in multiple words till enter is pressed. Example,

try (BufferedReader breader = new BufferedReader(new InputStreamReader(System.in))) {
   System.out.println("Enter a line:");
   String input = breader.readLine();
   System.out.println("User input is: " + input);
} catch (IOException e) {
   e.printStackTrace();
}

Output of this code is

Enter a line:
This is a test
User input is: This is a test

Hope the article was useful.