Java I/O
TL;DR
- The Java I/O (Input/Output) API (
java.iopackage) is used to read and write data to/from data sources like Files, Networks, or Memory. - It is based on the concept of Streams, which represent a continuous flow of data.
- The API is heavily categorized by data type: Byte Streams (for binary data like images) and Character Streams (for text data).
Concept
Imagine trying to read a 10GB movie file into a Java application with a 1GB memory limit. You cannot load the whole file at once.
The I/O Stream abstraction solves this. A Stream acts like a pipe connected to the file. You open the tap (the stream), read the data a few bytes at a time, process it, and pour it out the other end (e.g., to a network socket).
The java.io package uses the Decorator Design Pattern extensively. You take a basic FileInputStream, wrap it in a BufferedInputStream for performance, and then wrap that in a DataInputStream to read native Java primitives easily.
The Four Pillars of Java I/O
InputStream: Reads bytes (8-bit).OutputStream: Writes bytes (8-bit).Reader: Reads characters (16-bit Unicode).Writer: Writes characters (16-bit Unicode).
Examples
import java.io.*;
public class IoDemo {
public static void main(String[] args) {
// 1. Basic Byte Stream Example
// Using try-with-resources to automatically close the streams
try (InputStream in = new FileInputStream("input.jpg");
OutputStream out = new FileOutputStream("output.jpg")) {
int byteRead;
// Read one byte at a time until end of file (-1)
while ((byteRead = in.read()) != -1) {
out.write(byteRead); // Write that byte
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Interview Questions
Q: What is the difference between a Byte Stream and a Character Stream?
A: - Byte Streams (InputStream / OutputStream) read and write raw 8-bit bytes. They are strictly used for binary data, such as images, audio files, or compiled .class files.
- Character Streams (
Reader/Writer) read and write 16-bit Unicode characters. They automatically handle character encoding (like translating UTF-8 bytes from a file into Java’s internal UTF-16 characters). They are used exclusively for text files (like.txt,.xml,.json).
Q: Why must I/O Streams always be closed?
A: Streams rely on low-level operating system resources (like File Descriptors or Network Sockets). The Operating System strictly limits how many files a single process can have open simultaneously (e.g., 1024 on Linux). If you forget to close a stream, the JVM leaks the file descriptor. Eventually, your application will crash with a Too many open files exception. Always use Java 7’s try-with-resources block to guarantee automatic closure, even if an exception is thrown.