What is the difference between Java's BufferedReader and InputStreamReader classes?

63,591

Solution 1

BufferedReader is a wrapper for both "InputStreamReader/FileReader", which buffers the information each time a native I/O is called.

You can imagine the efficiency difference with reading a character(or bytes) vis-a-vis reading a large no. of characters in one go(or bytes). With BufferedReader, if you wish to read single character, it will store the contents to fill its buffer (if it is empty) and for further requests, characters will directly be read from buffer, and hence achieves greater efficiency.

InputStreamReader converts byte streams to character streams. It reads bytes and decodes them into characters using a specified charset. The charset that it uses may be specified by name or may be given explicitly, or the platform's default charset may be accepted.

Hope it helps.

Solution 2

Reading from main memory is faster than reading from disk/STDIN.

BufferedReader uses a technique called buffering that allows us to reduce how often we read from disk/STDIN by copying chunks to main memory.

Consider:

BufferedReader in = new InputStreamReader(System.in);
in.read(); // 
in.read(); //
// ...
in.read(); // could be hitting the disk/STDIN a lot (slow!)

vs:

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
in.read(); //
in.read(); //
// ...
in.read(); // hitting main memory a lot (fast!)

From the documentation:

Without buffering, each invocation of read() could cause bytes to be read from [disk/STDIN], converted into characters, and then returned, which can be very inefficient.

The two classes implement the same interface of Reader. So while you could use just InputStreamReader without BufferedReader, it could result in poor performance. We are just using the decorator pattern here so that we end up with a InputStreamReader which now has a buffering capability.

Solution 3

The InputStreamReader class adapts type InputStream (uninterpreted bytes) to the Reader class (bytes interpreted as characters in some character set), but does not apply any additional buffering. The BufferedReader class takes a Reader class (presumably unbuffered) and applies buffering to it.

Solution 4

BufferedReader reads a couple of characters from the specified stream and stores it in a buffer. This makes input faster.

InputStreamReader reads only one character from specified stream and remaining characters still remain in the stream.

Example:

class NewClass{    
    public static void main(String args[]) throws IOException{

        BufferedReader isr = new BufferedReader(new InputStreamReader(System.in));

        Scanner sc = new Scanner(System.in);

        System.out.println("B.R. - "+(char)isr.read());
        System.out.println("Scanner - " + sc.nextLine());       
    }
}

When the isr.read() statement is executed, I entered the input ”hello” and the character “h” of “hello” is printed on the screen. If this was InputStreamReader then the remaining characters “ello” would have remained in the System.in stream and the sc.nextLine() would have printed them. But in this case it doesn’t happens because the BufferedReader reads all of the “hello” characters from the System.in stream and stores them in its own personal buffer and thus the System.in stream remains empty when sc.nextLine() is executed.

For the code:

class NewClass{    

    public static void main(String args[]) throws IOException{

        InputStreamReader isr = new InputStreamReader(System.in);

        Scanner sc = new Scanner(System.in);

        System.out.println("I.S.R. - "+(char)isr.read());
        System.out.println("Scanner - " + sc.nextLine());

    }
}

In this case InputStreamReader reads only one character for “hello” input and the remaining “ello” still remain in the System.in stream and these characters are printed by sc.nextLine();

Conclusion:

BufferedReader reads a couple of characters(even if we want only one character it will read more than that) from the Input Stream and stores them in a buffer. That’s why it is called BufferedReader. I was unable to figure out how much characters it read in one go. It varied from 3 to 10 when I tested it for this answer.

InputStreamReader reads only one character from input stream and remaining characters still remain in the stream. There is no intermediate buffer in this case.

When one or more Threads or objects want to read characters from System.in then in that case InputStreamReader should be used because it reads only one character and remaining can be used by other objects or threads.

BufferedReader is fast because it maintains a buffer and retrieving data from buffer is always fast as compared to retrieving data from disk/stdin.

Solution 5

BufferedReader reads a couple of characters from the Input Stream and stores them in a buffer.

InputStreamReader reads only one character from the input stream and the remaining characters still remain in the streams hence There is no buffer in this case.

Share:
63,591
Ajay Yadav
Author by

Ajay Yadav

Updated on July 09, 2022

Comments

  • Ajay Yadav
    Ajay Yadav almost 2 years

    What is the difference between Java's BufferedReader and InputStreamReader classes?

  • Ajay Yadav
    Ajay Yadav over 12 years
    amod I want to use these classes to store the content of a webpage .I want to know either i should use BufferedReader or InputStreamReader ?
  • amod
    amod over 12 years
    @ajay i am not much sure about this.. but i read somewhere that BufferReader is efficient.
  • Quazi Irfan
    Quazi Irfan over 9 years
    "buffering" what does it mean?
  • Michael Aaron Safyan
    Michael Aaron Safyan about 9 years
    Buffering means that data is aggregated in an array called a "buffer". The use of a buffer makes reads more efficient in that you copy large chunks from the network to the buffer at a time even if you only read a small amount from the buffer at a time. It also makes it possible to reread content that has already been consumed (by moving back to an earlier position in the buffer which is what "mark"/"reset" do ).
  • Asif Mushtaq
    Asif Mushtaq about 8 years
    When to use read() byte by byte and when to use read(byte[]) array of byte. As I think reading array is always better. then can you give me example where to use one both of them?
  • Jacqueline P.
    Jacqueline P. over 4 years
    When I run your example in My IDE (Intellij), both B.R and I.S.R returns me a char "h" and neither Scanner execute, unless I enter another line (or enter "Enter"). However, given your explanation, for the latter example, the code "Scanner sc = new Scanner(System.in);" should be executed automatically and corresponding print result should be expected "Scanner - e"; do you know why there is a difference ? thank you!
  • Chaitanya Vaishampayan
    Chaitanya Vaishampayan over 4 years
    @JacquelineP. Maybe it is because for InputStreamReader, there may be a tiny buffer maintained internally, so when you type "hello", the whole string is read from the stream and stored in internal buffer and thus the Scanner is waiting for some other input to be entered as the stream now is empty. So, try entering a very long string of maybe 50 or more characters and then see, or maybe try entering a big sentence with spaces and then see the results.
  • VR7
    VR7 over 3 years
    for competitive coding, should I be using BufferedReader or InputReader
  • KnockingHeads
    KnockingHeads almost 3 years
    Probably, this is the best explanation. Adding for those, who are confused about not getting the desired result as explained by @ChaitanyaVaishampayan, enter a very large string in both the cases. In first case, you will see that when the buffer is full, then all remaining characters from large string will be printed by Scanner object. For the second case, the first character of the large string will be printed by InputStreamReader object while from second character till the end will be printed by the scanner object.
  • KnockingHeads
    KnockingHeads almost 3 years
    This is the one answer which does not explain what is there in books and google. But, it explains the concept to the very core with example. Thanks for this.
  • VanechikSpace
    VanechikSpace almost 2 years
    @ChaitanyaVaishampayan I've tried! Unfortunately, no matter how many characters i have entered, the result is the same all the time - scanner always requires one more enter :(
  • VanechikSpace
    VanechikSpace almost 2 years
    @ChaitanyaVaishampayan it's weird. Before i've executed this program in linux console, but i have just tried to execute it in ide on windows and i've been able to fill the buffer and reach that the characters, has left in the stream, have been read by scanner automatically. For some reason the result depending on OS. Why ?