102

I just learned about input/output using BufferedReader.

I wanted to know what exactly are the meanings of the term Stream and Buffer?

Also what does this line of code serves us:

BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
pb2q
  • 58,613
  • 19
  • 146
  • 147
user122345656
  • 1,523
  • 5
  • 15
  • 20

5 Answers5

225

Java has two kinds of classes for input and output (I/O): streams and readers/writers.

Streams (InputStream, OutputStream and everything that extends these) are for reading and writing binary data from files, the network, or whatever other device.

Readers and writers are for reading and writing text (characters). They are a layer on top of streams, that converts binary data (bytes) to characters and back, using a character encoding.

Reading data from disk byte-by-byte is very inefficient. One way to speed it up is to use a buffer: instead of reading one byte at a time, you read a few thousand bytes at once, and put them in a buffer, in memory. Then you can look at the bytes in the buffer one by one.

Oracle's Java tutorial about I/O explains it in detail.

Looking at the line of code you provided:

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

System.in is an InputStream. You create an InputStreamReader which reads bytes from System.in. Then you wrap that in a BufferedReader.

So, in the end, you have a BufferedReader that reads from an InputStreamReader that reads from System.in.

Jesper
  • 202,709
  • 46
  • 318
  • 350
  • 2
    Thank you for your answer but i have a confusion.As you said we read few thousands bytes at once and put them in buffer;so does this means that buffer is just a place in memory where we are storing things? – user122345656 Apr 13 '13 at 06:17
  • 3
    @Jesper . You said "One way to speed it up is to use a buffer: instead of reading one byte at a time, you read a few thousand bytes at once, and put them in a buffer, in memory. Then you can look at the bytes in the buffer one by one." Yes its true but i think with buffer also ,single byte is read at a time.The only difference i think it is put in the buffer and program then read it from buffer instead of disk – M Sach Apr 13 '13 at 06:20
  • 9
    @user122345656 Yes, a buffer is a place in memory to temporarily store data. – Jesper Apr 13 '13 at 20:16
  • 17
    @MSach Think of what happens when you want to read data from a harddisk. To read a byte at a certain location, you have to wait until the disk has rotated until the head is above the location on disk where the byte to be read is. If you'd read just 1 byte at that moment, and the next byte later, you'd have to wait until the disk has made a full rotation to read the next byte. It's much more efficient to read a block of consecutive bytes. – Jesper Apr 13 '13 at 20:18
  • WOW ! Very good answer. Very easy to understand, and to the point. – cram2208 Jun 09 '16 at 00:52
  • @Jesper In the above example, System.in reads byte-by-byte or in chunks? Is System.in aware of the BufferedReader outside and reads in chunks(In general, which one happens first - System.in or BufferedReader)? My natural guess is System.in since that is the starting point. If so, it will not have any knowledge of BufferedReader and hence no bulk reading and hence what is the use of BufferedReader in this example? Can you please split up the execution even more granular? – user104309 Mar 26 '17 at 18:46
  • I think I didn't give much thought into this. Only after some read method of BufferedReader is called, it instructs underlying reader(which inturn instructs stream) to read in bulk and keep it in buffer. Execution goes into StreamDecoder class which must be referring to System.in underneath and StreamDecoder has a provision (API) to read in bulk and hence it would read in bulk from the underlying stream which is System.in, here. – user104309 Mar 26 '17 at 19:33
  • @Jesper Will there still be a performance benefit even if the source is read only once(without any operations like mark and reset) with buffered technique(compared to an un-buffered one)? – lupchiazoem Apr 03 '18 at 14:48
  • @San Yes, because reading byte-by-byte from something like a harddisk is inefficient; it doesn't matter if you read the bytes just once or multiple times. – Jesper Apr 04 '18 at 09:19
  • But what's the difference between `InputStreamReader` and `InputStream`? I can read from `InputStream` using `inputstream.read()` method, or `inputstream.read(byte[])` method. What's the need for `InputStreamReader`? – parsecer May 06 '19 at 23:22
  • 2
    @parsecer Streams are for reading bytes; readers are for reading text (characters). `InputStreamReader` is a wrapper around an `InputStream` that allows you to read text from an `InputStream`. If you just want to read bytes (not characters), you don't need `InputStreamReader`. It's useful if you want to interpret the bytes as text characters. – Jesper May 07 '19 at 06:58
  • @Jesper Thank you for the reply! Got it. – parsecer May 07 '19 at 14:09
  • @Jesper "a buffer is a place in memory to temporarily store data". Isn't all memory a place to temporarily store data? – Juan Perez Jun 20 '23 at 07:57
32

Buffer:

It is a region of a physical memory storage used to temporarily store data while it is being moved from one place to another. That physical memory storage would be RAM (Random-access memory) in most cases.

But from this question's context, Buffer is used while reading/writing data. It need not be used while moving data from one place to another.

Example for buffer: If your system has 4 GB of RAM, 4 KB of memory(RAM) could be allocated for Buffer by the system. KB - Kilobyte(s), GB - Gigabyte(s)

I/O Stream (or) Stream:

I/O Stream represents an input source or an output destination. A stream can represent many different kinds of sources and destinations, including disk files, devices, other programs, and memory arrays.

I/O means Input/Output.

So, Input Stream can be an input source like disk file, network connection, etc.

And, Output Stream can be an output destination like disk file, network connection, etc.

According to JAVA official documentation, Streams are of 3 types.

  1. Byte Streams (read or write Bytes)
  2. Character Streams (read or write Characters)
  3. Buffered Streams (read from, or write to, Buffer for efficiency)

Byte Streams:

They perform input and output of 8-bit bytes. All byte stream classes are descended from InputStream and OutputStream.

Byte Input Stream classes obtain input as raw bytes. Byte Output Stream classes give output as raw bytes.

InputStream - Direct Known Subclasses

AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream, InputStream, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream.

OutputStream - Direct Known Subclasses

ByteArrayOutputStream, FileOutputStream, FilterOutputStream, ObjectOutputStream, OutputStream, PipedOutputStream

Character Streams: They are a layer on top of Byte Streams. They convert bytes(binary data) to characters and characters to bytes, using a character encoding.

All character stream classes are descended from Reader and Writer.

Reader - Direct Known Subclasses

BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader

Writer - Direct Known Subclasses

BufferedWriter, CharArrayWriter, FilterWriter, OutputStreamWriter, PipedWriter, PrintWriter, StringWriter

Byte Streams & Character Streams use unbuffered I/O.

This means each read or write request is handled directly by the underlying OS. This can make a program much less efficient, since each such request often triggers disk access, network activity, or some other operation that is relatively expensive. To reduce this kind of overhead, the Java platform implements buffered I/O streams.

Buffered Streams:

Buffered input streams read data from a memory area known as a buffer; the native input API is called only when the buffer is empty.

Similarly, buffered output streams write data to a buffer, and the native output API is called only when the buffer is full.

A program can convert an unbuffered stream into a buffered stream using the wrapping idiom, where the unbuffered stream object is passed to the constructor for a buffered stream class.

Example:

inputStream = new BufferedReader(new FileReader("xanadu.txt"));
outputStream = new BufferedWriter(new FileWriter("characteroutput.txt"));

There are 4 buffered stream classes which are used to wrap unbuffered streams:

To create buffered Byte Streams use, BufferedInputStream and BufferedOutputStream classes.

To create buffered Character Streams use, BufferedReader and BufferedWriter classes.

AnV
  • 2,794
  • 3
  • 32
  • 43
14

Well its a question in everbodys mind who start working on java.io package. To answer your question terms InputStreamReader and BufferedReader represent the java objects only(there is nothing special about them) but they are created for io operations like reading and writing from/to different inputs/outputs like file, object etc

Now lets come to line

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

InputStreamReader is the class to read the input stream of bytes.But to read each byte is expensive operation so we are wrapping it around BufferedReader to have it buffered( which is decorator pattern)

So what will happen is even before you start read, bufferedReader will store some chunk of bytes in register and when you perform read operation. it will be read from that location which is much less expensive than reading from console/file But in case of InputStreamReader, when you perform read operation each time disk access operation takes place

M Sach
  • 33,416
  • 76
  • 221
  • 314
3

A stream is the connection and actual information being passed between points. The buffer is a storage container which stores part or all of the streamed data and feeds this to the output device.

Of course, the point being that if the stream slows beyond the data rate required to show the data, then the output would pause. The buffer prevents this.

PGallagher
  • 3,123
  • 2
  • 26
  • 37
  • Thanks for ans.But a question that came in my mind is what do you mean by streamed data?Plz elaborate this. – user122345656 Apr 14 '13 at 05:01
  • 1
    Sorry for the late reply. If you imagine simple example of a 10Mb File on the Server. The Server has the full file, but it cannot send the whole file in one Packet. Instead, the file is split up into a finite number of blocks. Each block is then sent to the remote computer, and reassembled. For streaming live data, the same theory applies. But the server takes the live data and sends it as a `stream` of packets. The remote Computer then stores each Packet in a Buffer. The remote Computer reads the data from it's buffer and creates say a video from this. I hope this helps! – PGallagher Apr 16 '13 at 11:56
2

A Buffer is a portion in the memory that is used to store a stream of data from peripheral devices. Then from this buffer this stream of data is collected and stored in variables. A stream can be defined as a continuous flow of data.

The very term “input/output” means nothing more than moving data in and out of buffers. Just keep this in your mind all the time. Processes perform I/O by requesting of the operating system that data to be drained from a buffer (write operation) or that a buffer be filled with data (read operation).
Logical Diagram of how data moves

In simple terms, imagine when you type data in a keyboard, the data moves through a pipe(the stream) to the buffer and then from buffer to the disk(write operation). Similarly when data moves from disk to buffer and from buffer to your console then it is read operation.

You can read the links for better understanding. Hope it helps!.
What is buffer in Java
enter link description here

Kushagra
  • 89
  • 11