Java I/O

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 5 min

TL;DR

  • The Java I/O (Input/Output) API (java.io package) 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

  1. InputStream: Reads bytes (8-bit).
  2. OutputStream: Writes bytes (8-bit).
  3. Reader: Reads characters (16-bit Unicode).
  4. 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.