Java I/O Basics
We already know that data and operations on data are important parts of a computer program. Sometimes our application will need to read input data from a file or write the output data to a file. Java offers classes in the java.io package to facilitate these input/output (I/O) operations. Data can be of various types, ranging from raw bytes to characters, to primitive data types, and to objects.
Java treats I/O in a standard, uniform way in the form of streams. Conceptually, a stream on one end is connected to an I/O device (e.g. a file or a socket), to another stream (or a program), and ultimately to a program on the other end. The data flows between a program and the I/O device through these streams.
Only a low-level stream capable of reading bytes or characters can be directly connected to an I/O device, while a computer program can be connected to a low-level or a high-level stream. A high-level stream does some kind of data processing; it converts the low-level data (e.g. bytes and characters) into high-level data (e.g. primitive data types). Because in the I/O devices (such as a file) the data always lives in the form of bytes or characters, we cannot directly connect a high-level stream to an I/O device. Instead, a high-level stream is connected to a low-level stream, which in turn is connected to an I/O device.
From the perspective of a Java application, the data falls into three categories: raw bytes and characters, primitive data types, and objects. So, the focus of this chapter is to understand how to perform I/O in a Java program by using streams. To accomplish that, we explore three paths: how to read and write data in binary format (including bytes and data types), how to read and write data in text format, and how to read and write objects.
Java I/O Streams
An I/O Stream in Java represents an input source or an output destination. A stream can represent many different kinds of sources and destinations, including disk files, devices, other programs, and memory arrays. Streams support many different kinds of data, including simple bytes, primitive data types, localized characters, and objects. Some streams simply pass on data; others manipulate and transform the data in useful ways.
No matter how they work internally, all streams present the same simple model to programs that use them: A stream is an ordered sequence of data. Speaking alternatively, a stream in Java is a path along which data flows (like a pipe along which water flows). It has a source (of data) and a destination (for that data).
Java streams are classified into two basic types, namely, input stream and output stream. An input stream extracts (i.e. reads) data from the source and sends it to the program. Similarly, an output stream takes data from the program and sends (i.e. writes) it to the destination.
Figures 1 and 2 below illustrate the use of I/O streams. The program connects and opens an input stream on the data source and then reads the data serially. Similarly, the program connects and opens an output stream to the destination place of data and then writes data out serially. In both the cases, the program does not know the details of end points (i.e. source and destination).
A program uses an input stream to read data from a source, one item at a time:
Figure 1: Reading information into a program
A program uses an output stream to write data to a destination, one item at time:
Figure 2: Writing information from a program
In the next section, we will talk about the Java I/O Stream Classes.