Reader & Writer

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

TL;DR

  • Reader and Writer are the abstract base classes for all Character-Oriented I/O in Java.
  • They process data as 16-bit Unicode characters (char), making them the correct tool for reading and writing text files.
  • They act as a bridge, automatically converting raw bytes from the file into Java characters using a specified character encoding (like UTF-8).

Concept

If a file on a Linux hard drive contains the word “Hi”, it is stored as raw binary bytes (e.g., 01001000 01101001 in ASCII).
Java internally stores all characters as 16-bit Unicode (char).

If you use a basic byte InputStream, you have to read the raw bytes and manually translate them into Java Characters.
Reader and Writer classes do this automatically. When you call Reader.read(), it pulls bytes from the underlying file, checks the character encoding (e.g., UTF-8), decodes the bytes, and returns a fully formed Java character.

Common implementations include FileReader and FileWriter.

Examples

import java.io.*;

public class CharacterStreamDemo {
    public static void main(String[] args) {
        
        // 1. WRITING TEXT
        // FileWriter assumes the platform's default encoding (usually UTF-8)
        try (Writer writer = new FileWriter("greeting.txt")) {
            writer.write("Hello, World!\n");
            writer.write("I love Java I/O.");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 2. READING TEXT
        try (Reader reader = new FileReader("greeting.txt")) {
            int charRead;
            // Reads one character at a time. Handles multi-byte characters automatically!
            while ((charRead = reader.read()) != -1) {
                // Cast the int back to a char to print it
                System.out.print((char) charRead); 
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Interview Questions

Q: What is InputStreamReader and OutputStreamWriter?
A: They are Bridge Classes that connect the Byte Stream world to the Character Stream world.
If you are reading data from a raw Network Socket, the socket gives you an InputStream (bytes). To read text from it, you must wrap it: Reader r = new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8);. This bridge takes the raw bytes from the socket, applies the UTF-8 decoding algorithm, and outputs characters.

Q: Why should you always specify the Charset when using FileReader or FileWriter?
A: Prior to Java 11, FileReader had no constructor that accepted a Charset. It blindly used the operating system’s default encoding (e.g., Windows-1252 on Windows, UTF-8 on Mac/Linux). If you wrote a file on Windows and read it on a Mac, all special characters would be corrupted.
In Java 11+, they finally added constructors that accept a Charset. You should always explicitly pass StandardCharsets.UTF_8 to ensure your application behaves identically across all environments.