I/O Basics in Java With Examples

In this lecture, we will discuss the basics of Java I/O i.e Input/Output system. Java provides comprehensive and consistent support for I/O related to files and networks. We will be limiting our discussion to Streams, which is the fundamental of I/O operations.

Streams

Java programs perform I/O operations using streams. It is a sequence of data. It is an abstraction that either consumes or produces information. It is linked to a physical device by the Java I/O system. The behavior of the stream stays the same despite the difference in the actual linked physical device.  As a result, an I/O class and its method can be applied to a range of devices.

Hence, an input stream can abstract any kind of input: keyboard, file, or a network. Similarly, an output stream may refer to the console, file, or a network. Java implements streams within class hierarchies defined in the java.io package.

Types of Streams

Java defines two types of streams:

  • Byte
  • Character

Besides, there are three pre-defined stream variables:

  • in
  • out
  • err

Byte Streams

Byte streams provide a convenient way for handling the I/O of bytes. Byte streams are used, for example, when reading or writing binary data. It is part of Java since its first release i.e Java 1.0.

Byte streams are defined by using two-class hierarchies. At the top, there are two abstract classes:

  • InputStream
  • OutputStream

Each of these is an abstract class and are inherited by various child classes that handle the differences among various devices, such as files, network, or memory buffers. They define several key methods( read() and write()) for them to be inherited and implemented. The Byte stream classes in java.io are shown in the below table.

Class Purpose
BufferedInputStream Buffered Input Stream
BufferedOutputStream Buffered Output Stream
ByteArrayInputStream An input stream that reads from a byte array
ByteArrayOutputStream Output stream that writes to a byte array
FileInputStream An input stream that reads from a file
FileOutputStream Output stream that writes to a file
InputStream An abstract class that defines stream input
OutputStream An abstract class that defines stream output

Character Streams

Character streams provide a convenient way for handling the I/O of characters. They use Unicode and, hence, can be internationalized. Character Streams was added by Java 1.1, and post-integration, certain byte-oriented classes, and methods were deprecated. In some cases, Character streams are more efficient than Byte streams, so the advantage of character streams should be utilized where appropriate.

Character streams are defined by using two-class hierarchies. At the top, there are two abstract classes:

  • Reader
  • Writer

 Each of these is abstract classes handle Unicode character streams and are inherited by various child classes that handle the differences among various devices, such as files, network, or memory buffers. They define several key methods( read() and write() ) for them to be inherited and implemented. The character stream classes in java.io are shown in the below table.

Class Purpose
BufferedReader Buffered Input Character Stream
Buffered Writer Buffered Output Character Stream
CharArrayReader An input stream that reads from a character array
CharArray Writer Output stream that writes to a character array
FileReader An input stream that reads from a file
File Writer Output stream that writes to a file
Reader An abstract class that describes character stream input
Writer An abstract class that describes character stream output
InputStreamReader Input Stream that translates bytes to characters
OutputStreamReader Output Stream that translates characters  to bytes

Pre-defined Streams

All the stream variables i.e in, out, and err are declared as public, static, and final within class java.lang.System. This means that they can be used anywhere without the use of any reference of a System object.

System.in refers to standard input, which is the keyboard by default. It is an object of InputStream.

System.out refers to the standard output stream, which is console by default. It is an object of PrintStream.

System.err refers to the standard error stream, which is console by default. Similar to System.out, it is also an object of PrintStream.

It must be noted that all these are byte streams, even though they are typically used to read and write characters from and to the console. One can wrap these within character-based streams.

This was an overview of the basics of Java I/O. We will discuss I/O using the console in the next lecture.