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

6

60

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

Selfrighteous answered 11/9, 2011 at 6:15 Comment(6)
Also Tell Abt DataInputStream ClassSelfrighteous
@amod0017 the question is fully answered in the Javadoc. Asking questions on forums that have well-specified answers in the product documentation is to be discouraged as a very bad habit. It just wastes valuable time. The correct answer is already in the Javadoc and any response here will either quote it verbatim, which the OP could have already read, or else paraphrase it which is a loss of value and precision. And asking an question that you could answer yourself on a forum, and waiting possibly forever, for a possibly incorrect answer. isn't a rational learning strategy.Pepe
@EJB i do agree you but i guess the question that is asked is presented in a wrong way... he has some particular input on some web application and he just want to ask which he should prefer... as he is confused between the both... just simple as that.Burnoose
If I were to rephrase the question, I would ask: "Under what conditions would I NOT want to buffer a an input stream reader?" It seems the buffer is used pretty much by default everywhere.Wilderness
@AjayYadav Can you please change the accepted answer to ChaitanyaVaishampayan's answer. Totally depends on you, but, maybe you need to revisit his answer which is explained to such detail.Vibratile
@Burnoose I'm commenting on the question that was asked. You're just guessing. You don't know what he has. There is not one word about web applications in the question.Pepe
B
62

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.

Burnoose answered 11/9, 2011 at 6:21 Comment(4)
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 ?Selfrighteous
@ajay i am not much sure about this.. but i read somewhere that BufferReader is efficient.Burnoose
for competitive coding, should I be using BufferedReader or InputReaderSim
BufferedReader is a wrapper for any Reader.Pepe
T
38

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.

Tubby answered 2/5, 2016 at 14:59 Comment(1)
This code does not compile.Pepe
G
18

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.

Gild answered 11/9, 2011 at 6:21 Comment(3)
"buffering" what does it mean?Zolnay
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 ).Gild
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?Mathison
S
10

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.

Swale answered 15/10, 2017 at 7:18 Comment(7)
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!Wain
@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.Swale
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.Vibratile
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.Vibratile
@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 :(Expertise
@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 ?Expertise
BufferedReader reads an unpecified number of characters from the input reader, but it certainly far more than just 'a couple'. In fact it is 4096.Pepe
D
2

BufferedReader is a class in Java that reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, lines and arrays. The buffer size may be specified. If not, the default size, which is predefined, may be used.

In general, each read request made of a Reader causes a corresponding read request to be made of the underlying character or byte stream. It is therefore good practice to wrap a BufferedReader around any Reader whose read() operations may be costly, such as FileReaders and InputStreamReaders. For example,

FileReader reader = new FileReader(“MyFile.txt”);
BufferedReader bufferedReader = new BufferedReader(reader);

will buffer the input from the specified file. Without buffering, each invocation of read() or readLine() could cause bytes to be read from the file, converted into characters, and then returned, which can be very inefficient.

Source: https://medium.com/@isaacjumba/why-use-bufferedreader-and-bufferedwriter-classses-in-java-39074ee1a966

Destiny answered 15/12, 2019 at 16:31 Comment(0)
R
-2

As I understand that instead of InputStreamReader BufferedReader takes less time to convert the data from bytes to character.so we prefer BufferedReader for better performance

Reconnoitre answered 6/10, 2017 at 13:25 Comment(1)
You do not understand correctly. BufferedReader doesn't do any conversions at all. See the Javadoc. This is not the point of difference.Pepe

© 2022 - 2024 — McMap. All rights reserved.