Another interesting feature of streams is that you can combine multiple streams together into chains. A stream can read data not only from its internal data source, but also from another stream.
This is a very powerful mechanism in Java, which makes it possible to create complex data reading scenarios by connecting one stream to another. Such a scheme looks like this:
When a program reads data from a data stream, the data stream in turn reads the data from its data source, which is another data stream or a file, for example.
What's more, each data stream not only reads in and gives out data, but can also transform it or perform various operations on it. A good example of such an "intermediate stream" is the
We already know a class called
FileReader — it is a
Reader that reads data from a file. And where does
InputStreamReader get its data from? That's right — from an
When you create an
InputStreamReader object, you need to pass in an
InputStream object or one of its descendant classes. Example:
String src = "c:\\projects\\log.txt"; FileInputStream input = new FileInputStream(src); InputStreamReader reader = new InputStreamReader(input);
InputStreamReader class has all the methods that the
Reader class has, and they work in exactly the same way.
The main difference between the
InputStreamReader class and, say,
FileReader is where they read data from.
FileReader reads data from a file (duh — that's why it's called
InputStreamReader reads data from an
When you read a character from a
FileReader object using the
read() method, it in turn reads two bytes from the file on disk and returns them as
When you read a character from an
InputStreamReader object using the
read() method, it in turn reads two bytes from the
FileInputStream object passed to it, which in turn reads data from the file. The result is a chain of calls to
Another interesting class that you are likely to use a lot is
BufferedReader. This is also an "intermediate stream" that reads data from another stream.
As its name suggests, the
BufferedReader class is a subclass of
Reader and lets you read characters. But what is most interesting is that you also need to pass it a data source in the form of a stream from which characters can be read, i.e. a stream that inherits the
What's the point? Unlike
BufferedReader class does not convert bytes to characters: it doesn't convert anything at all. Instead, it buffers data.
When a program reads a single character from a
BufferedReader object, the object reads a large array of characters from its source stream all at once. And stores them internally.
When the next character is read from the
BufferedReader object, it simply grabs the next character from its internal buffer array and returns it without accessing the data source. Only when all the characters in the buffer are used up does it read in another large array of characters.
BufferedReader class also has a very useful method —
String readLine(), which lets you read entire strings of data from the source stream all at once. You can use this method to, say, read a file and display its contents on the screen line by line. Example:
We specifically wrote some compact code to illustrate how convenient this can be. This code could also be written with a little more detail.
As long as there is still data in the reader
Read one line
Display the line
If you chain together multiple streams, then the
close() method only needs to be called on one of them. That stream will call the method on its data source, and so on, until
close() is called on the final data stream.
3. Reading from the console
And one more interesting fact: the
Scanner class is nothing more than an intermediate input stream that reads data from
System.in, which is also a data stream.
Here are two ways to read a line from the console:
|Scanner class||BufferedReader and BufferedWriter classes|
System.in is nothing more than a static
in variable of the
System class. It is an
InputStream whose name is
So almost from the very beginning of your Java studies on CodeGym, you have been working with data streams and build chains from them. But now you will do it more consciously.