Specialized Streams Reference

Naveen AnamaneniUpdated · 4 min read
mediumJava 25javaioreference

Besides the everyday stream classes, java.io contains a handful of specialized streams built for particular jobs, such as joining several streams into one, "un-reading" a character, or connecting two threads. You will rarely need them, but you should recognize them when you meet them in older code or an interview. In this lesson, you will find a reference table of these classes and short examples of the two most useful ones.

Reference Table

ClassKindIt is used to...
SequenceInputStreamByte inputRead several input streams one after another, as if they were one.
PushbackInputStreamByte input decoratorPush bytes back so the next read returns them again (peeking ahead).
PushbackReaderCharacter input decoratorPush characters back, for writing simple parsers.
PipedInputStream / PipedOutputStreamBytes between threadsConnect a writing thread to a reading thread.
PipedReader / PipedWriterCharacters between threadsThe same, for text.
FilterInputStream / FilterOutputStreamByte decorator baseServe as the base class for your own byte decorators.
FilterReader / FilterWriterCharacter decorator baseServe as the base class for your own character decorators.
LineNumberReaderCharacter input decoratorRead lines while tracking the current line number.
StreamTokenizerParserSplit input into numbers, words and symbols (old, rarely used).
ObjectStreamFieldSerialization helperDescribe a serializable field when customizing serialization.

Example: SequenceInputStream

Let's see an example that reads two sources as one continuous stream.

Joined.java▶ Try it
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.nio.charset.StandardCharsets;
 
public class Joined {
    public static void main(String[] args) throws IOException {
        InputStream part1 = new ByteArrayInputStream(
            "Navika, Srihitha".getBytes(StandardCharsets.UTF_8));
        InputStream part2 = new ByteArrayInputStream(
            ", Advitha".getBytes(StandardCharsets.UTF_8));
 
        try (InputStream both = new SequenceInputStream(part1, part2)) {
            System.out.println(new String(both.readAllBytes(),
                                          StandardCharsets.UTF_8));
        }
    }
}
Output
Navika, Srihitha, Advitha

Explanation: SequenceInputStream reads part1 until it ends, then continues with part2, so the reader sees one stream. It is handy for joining files that were split into parts.

Example: PushbackReader for Peeking

Peek.java▶ Try it
import java.io.IOException;
import java.io.PushbackReader;
import java.io.StringReader;
 
public class Peek {
    public static void main(String[] args) throws IOException {
        try (PushbackReader r = new PushbackReader(new StringReader("42+7"))) {
            StringBuilder number = new StringBuilder();
            int c;
            while ((c = r.read()) != -1 && Character.isDigit(c)) {
                number.append((char) c);
            }
            if (c != -1) {
                r.unread(c);
            }
            System.out.println("Number: " + number);
            System.out.println("Next symbol: " + (char) r.read());
        }
    }
}
Output
Number: 42
Next symbol: +

Explanation: The loop reads digits until it meets a non-digit, the +. That character was read too early, so unread pushes it back, and the next read returns it again. This "read one too far, then push back" step is common in simple parsers.

Common Mistakes

Using piped streams in one thread. It can deadlock.

Pushing back more characters than the buffer allows. PushbackReader holds one character by default; pass a larger size to the constructor if needed.

Practice

  1. Easy: Join three StringReader-based texts by converting them to byte streams and using SequenceInputStream.
  2. Harder: Use a PushbackReader to split the text "12+34-5" into numbers and operators, printing each token on its own line.

Quick check: Specialized streams

4 questions
1Which class reads several streams one after another?
2What does unread do in a PushbackReader?
3What do piped streams connect?
4Which class is a base for writing your own byte decorator?

Key Takeaways

Was this tutorial helpful?

Lesson 352 of 482