The Basic Elements of Stream I/O

A stream is a popular concept for how to perform input/output to and from a program. Basically, a stream is a sequence of characters with functions to take characters out of one end, and put characters into the other end. In the case of input/output streams, one end of the stream is connected to a physical or logical I/O device, such as a keyboard, display, file, or queue. If it is an output stream, your program puts characters into one end of the stream, and an output device takes characters out of the other end. If it is an input stream, an input device puts characters into one end of the stream, and your program takes characters out of the other end.

The purpose of stream I/O is to simplify a programmer's view of input and output devices. The physical characteristics of I/O devices and the organization of data remain hidden. The data organization of devices is reduced to two simple forms:
  • A sequence of characters that can be read or written character by character
  • A sequence of lines that can be read or written line by line. A line in this context is defined as a sequence of characters that are terminated by means of any special character, or by means of the organizational form of the storage media.
A simple set of functions performs stream I/O operations from within a program.
  • Housekeeping functions declare streams as input or output streams, open and close streams before and after using them, and allow to query their existence and characteristics.
  • Character input and character output functions let the program read and write data character by character from input streams or to output streams.
  • Line input and line output functions let the program read and write data line by line from input streams or to output streams.
  • Further functions let the program check for the availability of input data from input streams.

During stream I/O operations a pointer is maintained for each stream. The pointer references the current position in a stream where a read operation or a write operation takes place. The position in a stream is relative to its beginning, counted as number of characters. Position 1 is always the first character. Pointers increase automatically during read operations and write operations. This eases the sequential reading from or writing to streams. The stream I/O functions can modify the position pointers by specifying explicit character or line positions to be read or written.

When streams are declared, they are given names. The input and output functions refer to these names to distinguish among multiple streams in a REXX program.

Generally, a stream can be any source or destination of external data that a program uses. Typical streams are files and data sets, and consoles for interactive input and output. The stream I/O concept also allows to view other sources and destinations as streams, for example, a reader, puncher, printer, program stack, queue, or a communication path. Programming environments that support stream I/O usually provide a default input stream, which is often the terminal input buffer, and a default output stream, often the display.

Data streams have two distinctive traits; they are either finite or conceptually unbound. An input stream from a file is finite because of the known quantity of characters; an input stream from a keyboard or communication path is unbound because of the unknown quantity. Stream I/O functions generally provide a mechanism of determining that an input stream is exhausted – that all data was read, and no more data is available. For finite streams they can detect the end of a file, for example. For unbound streams they might interpret special characters of the stream as delimiters.