| Input and Output Streams

## Overview of Input and Output Streams

> The java.io package contains two classes, InputStream and OutputStream, from which most of the other classes in the package derive.

> The InputStream class is an abstract superclass that provides a minimal programming interface and a partial implementation of input streams. The InputStream class defines methods for reading bytes or arrays of bytes, marking locations in the stream, skipping bytes of input, finding out the number of bytes available for reading, and resetting the current position within the stream. An input stream is automatically opened when you create it. You can explicitly close a stream with the `close()` method, or let it be closed implicitly when the InputStream is garbage collected which occurs when the object is no longer referenced.

> The OutputStream class is an abstract superclass that provides a minimal programming interface and a partial implementation of output streams. OutputStream defines methods for writing bytes or arrays of bytes to the stream. An output stream is automatically opened when you create it. You can explicitly close an output stream with the `close()` method, or let it be closed implicitly when the OutputStream is garbage collected which occurs when the object is no longer referenced.

> The java.io package contains several subclasses of InputStream and OutputStream that implement specific input or output functions. For example, FileInputStream and FileOutputStream are input and output streams that operate on files on the native file system.

> The first of the following two diagrams shows the class hierarchy for the input stream classes in the java.io package. The second diagram shows the class hierarchy for the output stream classes in the java.io package.

> Note: You can click on any of the class symbols in either diagram to visit the API documentation for that class.

> As you can see from the diagram InputStream inherits from the Object class; six classes inherit directly from InputStream. One of InputStream's descendants, FilterInputStream, is itself an abstract class with four children.

> As you can see OutputStream inherits from the Object class; four classes inherit directly from OutputStream. One of OutputStream's descendants, FilterOutputStream, is itself an abstract class with three descendants.

> #### Simple Input and Output Streams

> > The following is an overview of the non-abstract classes that subclass directly from InputStream and OutputStream:
> > FileInputStream and FileOutputStream
> >   Read data from or write data to a file on the native file system.
> > PipedInputStream and PipedOutputStream
> >   Implement the input and output components of a pipe. Pipes are used to channel the output from one program (or thread) into the input of another. A PipedInputStream must be connected to a PipedOutputStream and a PipedOutputStream must be connected to a PipedInputStream.
> > ByteArrayInputStream and ByteArrayOutputStream
> >   Read data from or write data to a byte array in memory.
> > SequenceInputStream
> >   Concatenate multiple input streams into one input stream.
> > StringBufferInputStream
> >   Allow programs to read from a StringBuffer as if it were an input stream.
> > Using Input and Output Streams, later in this lesson, covers these streams.

> #### Filtered Streams

> > FilterInputStream and FilterOutputStream are subclasses of InputStream and OutputStream, respectively, and are both themselves abstract classes. These classes define the interface for filtered streams which process data as it's being read or written. For example, the filtered streams BufferedInputStream and BufferedOutputStream buffer data while reading and writing to speed it up.
> > DataInputStream and DataOutputStream
> >   Read or write primitive Java data types in a machine independent format.
> > BufferedInputStream and BufferedOutputStream
> >   Buffer data while reading or writing thereby reducing the number of accesses required on the original data source. Buffered streams are typically more efficient than similar non-buffered streams.
> > LineNumberInputStream
> >   Keeps track of line numbers while reading.
> > PushbackInputStream
> >   An input stream with a one-byte pushback buffer. Sometimes when reading data from a stream it is useful to peek at the next character in the stream in order to decide what to do next. If you peek at a character in the stream, you'll need to put it back so that it can be read again and processed normally.
> > PrintStream
> >   An output stream with convenient printing methods.
> > The Working with Filtered Streams page, later in this lesson, shows you how to use filtered streams and how to implement your own.

> #### And the Rest...

> > In addition to the stream classes, java.io contains these other classes:
> > File
> >   Represents a file on the native file system. You can create a File object for a file on the native file system and then query the object for information about that file (such as its full pathname).
> > FileDescriptor
> >   Represents a file handle (or descriptor) to an open file or an open socket. You will not typically use this class.
> > RandomAccessFile
> >   Represents a random access file.
> > StreamTokenizer
> >   Breaks the contents of a stream into tokens. Tokens are the smallest unit recognized by a text-parsing algorithm (such as words, symbols, and so on). A StreamTokenizer object can be used to parse any text file. For example, you could use it to parse a Java source file into variable names operators and so on, or an HTML file into HTML tags, words and such.

> > And finally java.io defines three interfaces:

> > DataInput and DataOutput
> >   These two interfaces describe streams that can read and write primitive Java types in machine-independent format. DataInputStream, DataOutputStream, and RandomAccessFile implement these interfaces.
> > FilenameFilter
> >   The `list()` method in the File class uses a FilenameFilter to determine which files in a directory to list. The FilenameFilter accepts or rejects files based on their names. You could use FilenameFilter to implement simple regular expression style file search patterns such as foo.* and so on.
> > Using Random Access Files talks about how to use random access files. It also provides a special section that shows you how to write filters for objects that implement the DataInput and DataOutput interfaces. Filters implemented in this fashion are more flexible than regular filtered streams because they can be used on random access files and on some sequential files.

| Input and Output Streams