Chaining Streams Java
Java comes with low-level byte streams and high-level byte streams and similarly low-level and high-level character streams. Sub classes of FilterInputStream and FilterOutputStream are known as high-level streams. There are four high-level streams on input streams side – LineNumberInputStream, DataInputStream, BufferedInputStream and PushbackInputStream.
The job of high-level streams is to add extra functionality to the existing streams. For example, LineNumberInputStream adds line numbers in the destination file that do not exist in the source file. DataInputStream increases performance with its readInt() and readLine() methods etc.
For higher functionality, one stream can be linked or chained to another, but obeying some simple rules. Chaining is very simple. The output of one stream becomes input to the other. Or to say, we pass an object of one stream as parameter to another stream constructor; this is how chaining is affected.
Rules of chaining (Chaining Streams Java)
If streams are chained just like that, you will land in compilation errors. Following rules are to be followed.
- The input for a high-level stream may come from a low-level stream or another high-level stream. That is, in programming, the constructor of a high-level stream can be passed with an object of low-level or high-level.
- Being low-level, the low-level stream should work by itself. It is not entitled to get passed with any other stream.
In programming, the low-level stream opens the file and hand it over (passes) to a high-level stream. High-level stream cannot open a file directly. That is, high-level streams just add extra functionality and depend solely on low-level streams.
For example, see the following.
String str1 = "Accept\ngreetings\nfrom\nway2.java";
StringBufferInputStream sbi = new StringBufferInputStream(str1); // low-level
LineNumberInputStream lis = new LineNumberInputStream(sbi); // high-level
DataInputStream dis = new DataInputStream(lis); // high-level
Before going into explanation, let us find out what are low-level and high-level streams. In stream hierarchy, the subclasses of FilterInputStream and FilterOutputStream are known high-level streams and all the remaining are low-level.
The intention of code is to give line numbers to the words of string str1 separated by \n. This string is passed to the constructor of low-level StringBufferInputStream because StringBufferInputStream can hold a string. The sbi object is passed to the constructor of high-level LineNumberInputStream to give line numbers. Again, the lis object is passed to another high-level stream constructor DataInputStream which can read each line separately.
Here, the functionalities achieved with different streams chained are
- Low-level FileInputStream opens the file.
- High-level LineNumberInputStream adds line numbers.
- High-level DataInputStream reads line by line.