Java Reference
In-Depth Information
Once you understand that the class design for input streams in Java I/O is based on the decorator pattern, it
should be easy to construct an input stream using these classes. The superclass
InputStream
contains the basic
methods to read data from an input stream, which are supported by all concrete component classes as well as all
concrete decorator classes. The basic operation on an input stream is to read data from it. Some important methods
defined in the
InputStream
class are listed in Table
7-2
. Note that you have already used two of these methods,
read()
and
close()
, in the
SimpleFileReading
class to read data from a file.
Table 7-2.
Some Important Methods of the InputStream Class
Method
Description
read()
Reads one byte from the input stream and returns the read byte as an
int
. It
returns -1 when the end of the input stream is reached.
read(byte[] buffer)
Reads maximum up to the length of the specified
buffer
. It returns the number of
bytes read in the
buffer
. It returns -1 if the end of the input stream is reached.
read(byte[] buffer,
int offset, int length)
Reads maximum up to the specified
length
bytes. The data is written in the
buffer
starting from the
offset
index. It returns the number of bytes read or -1 if
the end of the input stream is reached.
Note
: The
read()
method blocks until the input data is available for reading, the end of the input stream is reached,
or an exception is thrown.
close()
Closes the input stream
available()
Returns the estimated number of bytes that can be read from this input stream
without blocking.
Let's briefly discuss the four input stream concrete decorators:
BufferedInputStream, PushbackInputStream
,
DataInputStream
, and
ObjectInputStream
. I will discuss
BufferedInputStream
and
PushbackInputStream
in this
section. I will discuss
DataInputStream
in the “Reading and Writing Primitive Data Types” section. I will discuss
ObjectInputStream
in the “Object” section.
BufferedInputStream
A
BufferedInputStream
adds functionality to an input stream by buffering the data. It maintains an internal
buffer to store bytes read from the underlying input stream. When bytes are read from an input stream, the
BufferedInputStream
reads more bytes than requested and buffers them in its internally maintained buffer. When a
byte read is requested, it checks if the requested byte already exists in its buffer. If the requested byte exists in its buffer,
it returns the byte from its buffer. Otherwise, it reads some more bytes in its buffer and returns only the requested
bytes. It also adds support for the mark and reset operations on an input stream to let you reread bytes from an input
stream. The main benefit of using
BufferedInputStream
is faster speed because of buffering.
Listing 7-17 demonstrates how to use a
BufferedInputStream
to read contents of a file. The code in this
listing reads the text in the
luci1.txt
file. The only difference between
SimpleFileReading
in Listing 7-15 and
BufferedFileReading
in Listing 7-17 is that the latter uses a decorator
BufferedInputStream
for a
FileInputStream
and the former simply uses a
FileInputStream
. In
SimpleFileReading
, you construct the input stream as follows:
String srcFile = "luci1.txt";
FileInputStream fis = new FileInputStream(srcFile);