15

Sorry if this question is a dulplicate but I didn't get an answer I was looking for.

Java docs says this

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 advisable to wrap a BufferedReader around any Reader whose read() operations may be costly, such as FileReaders >and InputStreamReaders. For example,

BufferedReader in = new BufferedReader(new FileReader("foo.in"));

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.

  1. My first question is If bufferedReader can read bytes then why can't we work on images which are in bytes using bufferedreader.

  2. My second question is Does Bufferedreader store characters in BUFFER and what is the meaning of this line

will buffer the input from the specified file.

  1. My third question is what is the meaning of this line

In general, each read request made of a Reader causes a corresponding read request to be >made of the underlying character or byte stream.

TruePS
  • 493
  • 2
  • 12
  • 33

3 Answers3

12

There are two questions here.

1. Buffering

Imagine you lived a mile from your nearest water source, and you drink a cup of water every hour. Well, you wouldn't walk all the way to the water for every cup. Go once a day, and come home with a bucket full of enough water to fill the cup 24 times.

The bucket is a buffer.

Imagine your village is supplied water by a river. But sometimes the river runs dry for a month; other times the river brings so much water that the village floods. So you build a dam, and behind the dam there is a reservoir. The reservoir fills up in the rainy season and gradually empties in the dry season. The village gets a steady flow of water all year round.

The reservoir is a buffer.

Data streams in computing are similar to both those scenarios. For example, you can get several kilobytes of data from a filesystem in a single OS system call, but if you want to process one character at a time, you need something similar to a reservoir.

A BufferedReader contains within it another Reader (for example a FileReader), which is the river -- and an array of bytes, which is the reservoir. Every time you read from it, it does something like:

 if there are not enough bytes in the "reservoir" to fulfil this request
      top up the "reservoir" by reading from the underlying Reader
 endif
 return some bytes from the "reservoir".

However when you use a BufferedReader, you don't need to know how it works, only that it works.

2. Suitability for images

It's important to understand that BufferedReader and FileReader are examples of Readers. You might not have covered polymorphism in your programming education yet, so when you do, remember this. It means that if you have code which uses FileReader -- but only the aspects of it that conform to Reader -- then you can substitute a BufferedReader and it will work just the same.

It's a good habit to declare variables as the most general class that works:

 Reader reader = new FileReader(file);

... because then this would be the only change you need to add buffering:

 Reader reader = new BufferedReader(new FileReader(file));

I took that detour because it's all Readers that are less suitable for images.

Reader has two read methods:

 int read(); // returns one character, cast to an int
 int read(char[] block); // reads into block, returns how many chars it read

The second form is unsuitable for images because it definitely reads chars, not ints.

The first form looks as if it might be OK -- after all, it reads ints. And indeed, if you just use a FileReader, it might well work.

However, think about how a BufferedReader wrapped around a FileReader will work. The first time you call BufferedReader.read(), it will call FileReader.read(buffer) to fill its buffer. Then it will cast the first char of the buffer back to an int, and return that.

Especially when you bring multi-byte charsets into the picture, that can cause problems.

So if you want to read integers, use InputStream not Reader. InputStream has int read(byte[] buf, int offset, int length) -- bytes are much more reliably cast back and forth from int than chars.

slim
  • 40,215
  • 13
  • 94
  • 127
  • Thank you for writing such a long article for me.I really appreciate it, but the other users who answered they know how BufferedReader works,So i also wanted to enhance my knowledge regarding how it works,Certainly your article really increased my knowledge regarding how a **BufferedReader wrapped around a FileReader will work** and regarding **buffer** . – TruePS Mar 06 '14 at 12:13
  • Just wanted to say, great answer. – mxk Jul 22 '16 at 14:56
  • Very we well explained @Slim. – AwsAnurag Oct 30 '21 at 17:22
5

Readers (and Writers) in java are specialized classes for dealing with text (character) streams - the concept of a line is meaningless in any other type of stream.

for the general IO equivalent, have a look at BufferedInputStream

so, to answer your questions:

  1. while the reader does eventually read bytes, it converts them to characters. it is not intended to read anything else (like images) - use the InputStream family of classes for that
  2. a buffered reader will read large blocks of data from the underlying stream (which may be a file, socket, or anything else) into a buffer in memory and will then serve read requests from this buffer until the buffer is emptied. this behaviour of reading large chunks instead of smaller chucks every time improves performance.
  3. it means that if you dont wrap a reader in a buffered reader then every time you want to read a single character, it will access the disk.network to get just the single character you want. doing I/O in such small chunks is usually terrible for performance.
radai
  • 23,949
  • 10
  • 71
  • 115
  • can you answer that question [http://stackoverflow.com/questions/22199220/how-to-read-multiple-lines-using-filereader-only/22216055#22216055 ] .Plz help if you can – TruePS Mar 06 '14 at 06:14
  • i understood first and third point but didn't get the 2nd point does buffered reader creates a new buffer everytime it reads a line and Are you saying that buffered reader reads data from buffer so it saves our time? – TruePS Mar 06 '14 at 06:20
  • @TruePS - no, it works with a single buffer. it serves read requests from that buffer and when the buffer becomes empty it reads a chunk from the underlying stream/reader/whatever to fill the buffer. and yes, this improves performance considerably. – radai Mar 06 '14 at 06:26
  • Ok I got it now just I last thing let's say i have a text file test.txt containing three lines How are you? That means Bufferedreader firstly read first line i.e. How and places it in buffer,then it reads are and places it in buffer and then you and places it in buffer.Am I right?So when will buffer becomes empty? – TruePS Mar 06 '14 at 06:37
3
  1. Default behaviour is it will convert to character, but when you have an image you cannot have a character data, instead you need pixel of bytes data. So you cannot use it.

  2. It is buffereing, means , it is reading a certain chunk of data in an char array. You can see this behaviour in the code:

 public BufferedReader(Reader in) {
               this(in, defaultCharBufferSize);
            }

and the defaultCharBufferSize is as mentioned below:

private static int defaultCharBufferSize = 8192;

3 Every time you do read operation, it will be reading only one character.

So in a nutshell, buffred means, it will read few chunk of character data first that will keep in a char array and that will be processed and again it will read same chunk of data until it reaches end of stream

You can refer the following to get to know more

BufferedReader

UVM
  • 9,776
  • 6
  • 41
  • 66
  • let's say i have a text file test.txt containing three lines >How >are >you That means Bufferedreader firstly read first line i.e. How and places it in buffer,then it reads are and places it in buffer and then you and places it in buffer.Am I right?So when will buffer becomes empty? – TruePS Mar 06 '14 at 06:45
  • 1
    It will read n bytes or chars data and store into a char array instead of reading again and again from i/o. Remember every read operation, is costlier and will have impact on performance. Let us a file having is 20000 bytes, using buffering strategy, you will first read , say 512 bytes and store it an array, instead of reading a single byte every time for all these 20000 chars. – UVM Mar 06 '14 at 06:47
  • So it will read whole 3 lines How are you and stores it into a char array and char array is into a buffer in memory.So bufferedreader will read all the data from buffer and displays it and after reading all the data it empties the buffer.Am I right now? – TruePS Mar 06 '14 at 06:52
  • 2
    Reading to char array is BUFFERING. You can see that in the above link I mentioned. – UVM Mar 06 '14 at 06:57
  • the link you gave me is out of my league I just want to get the answer of my previous comment is that the whole process After that I won't waste your precious time,So plz help me by giving answer of my previous comment,plz plz. – TruePS Mar 06 '14 at 07:00
  • 1
    1. it will create a char array with a default size and read that many chars into that array, not line. Then it will form a line of string from this character array and return to you when you call readLine().How it is storing into char array, please go through the readLine() method in the above link. There you can see how this char array is used. Hope this is clear to you now. – UVM Mar 06 '14 at 07:08
  • I am a little unclear about readline() works but thank you for your tremendous help I wish I could chat with you regarding this topic your knowledge about Java is really awesome.Thank you so much. – TruePS Mar 06 '14 at 07:13