1) How does buffered streams work in background, how do they differ from normal streams and what are the advantage(s) of using them?
2) DataInputStream
is also Byte based. But it is having methods to readLine()
. What's the point in here?
From the BufferedInputStream javadoc:
A BufferedInputStream adds functionality to another input stream-namely, the ability to buffer the input and to support the mark and reset methods. When the BufferedInputStream is created, an internal buffer array is created. As bytes from the stream are read or skipped, the internal buffer is refilled as necessary from the contained input stream, many bytes at a time. The mark operation remembers a point in the input stream and the reset operation causes all the bytes read since the most recent mark operation to be reread before new bytes are taken from the contained input stream.
Internally a buffer array is used and instead of reading bytes individually from the underlying input stream enough bytes are read to fill the buffer. This generally results in faster performance as less reads are required on the underlying input stream.
The opposite is then true for BufferedOutputStream.
mark() and reset() could be used as follows:
1 BufferedInputStream bis = new BufferedInputStream(is);
2 byte[] b = new byte[4];
3 bis.read(b); // read 4 bytes into b
4 bis.mark(10); // mark the stream at the current position - we can read 10 bytes before the mark point becomes invalid
5 bis.read(b); // read another 4 bytes into b
6 bis.reset(); // resets the position in the stream back to when mark was called
7 bis.read(b); // re-read the same 4 bytes as line 5 into b
To explain mark/reset some more...
The BufferInputStream internally remembers the current position in the buffer. As you read bytes the position will increment. A call to mark(10) will save the current position. Subsequent calls to read will continue to increment the current position but a call to reset will set the current position back to its value when mark was called.
The argument to mark specifies how many bytes you can read after calling mark before the mark position gets invalidated. Once the mark position is invalidated you can no longer call reset to return to it.
For example, if mark(2) had been used in line 4 above an IOException would be thrown when reset() is called on line 6 as the mark position would have been invalidated since we read more than 2 bytes.