I/O Streams
In short: A data stream through which a program sequentially reads (input) or writes (output) data — the shared abstraction behind file, network, and console input/output.
In more detail: Streams usually process data piece by piece instead of all at once, which makes even very large amounts of data manageable without keeping them entirely in memory. A distinction is made between byte streams (raw bytes, e.g. FileInputStream) and character streams (text with character encoding), as well as unbuffered and buffered variants.
In Depth
The central advantage of a stream over “reading everything at once” shows up for large files: loading a 10 GB log file entirely into memory before processing it would exceed the available working memory in most systems — a stream instead always reads, for example, only the current line or a fixed block of bytes, processes it, and discards it again afterwards.
stream = open_file("huge_log_file.txt")
while stream.has_next_line():
line = stream.read_next_line()
process(line)
stream.close()Streams can be roughly distinguished along two axes:
- Direction: input stream (reading) vs. output stream (writing) — usually separate stream objects are needed for input and output, even if they address the same source/target.
- Buffering: an unbuffered stream asks the operating system/disk directly on every single read/write operation, which is slow for many small operations. A buffered stream first collects a larger block internally in memory (buffer) and passes data on from there — significantly faster for many small read/write calls, but costs some additional memory.
An important, often forgotten point: an open stream occupies an operating system resource (a file descriptor/handle) — if the stream isn’t explicitly closed (e.g. via close() or with a language construct like Java’s try-with-resources, which handles that automatically), this resource stays occupied, even once the program is done with the file. With many open, never-closed streams, a long-running program can eventually no longer open new files (“too many open files”).
See also: FileInputStream, BufferedReader, Files