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));
A stream is a sequence of bytes that is read and/or written to, while a buffer is a sequence of bytes that is stored.
A buffer is a linear, finite sequence of elements of a specific primitive type. Aside from its content, the essential properties of a buffer are its capacity, limit, and position: A buffer's capacity is the number of elements it contains. The capacity of a buffer is never negative and never changes.
A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result. The features of Java stream are – A stream is not a data structure instead it takes input from the Collections, Arrays or I/O channels.
Input/output (I/O) buffering is a mechanism that improves the throughput of input and output operations. It is implemented directly in hardware and the corresponding drivers and is also ubiquitous among programming language standard libraries.
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
.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With