← Back to Home

Character Streams

Character Streams in Java are used to read and write text data. They work with 16-bit Unicode characters, making them suitable for text files and internationalization.

This is a core Java I/O topic and a common interview question, often compared with Byte Streams.

What Are Character Streams?

  • Work with characters instead of bytes
  • Handle Unicode automatically
  • Support character encoding
  • Part of java.io package
  • Base classes:
    • Reader
    • Writer

When to Use Character Streams

  • ✔ Text files (.txt, .csv, .xml, .json)
  • ✔ Logs and configuration files
  • ✔ User-readable data
  • ✔ Language-specific characters
  • ❌ Not for binary data (images, audio, PDFs)

Character Stream Class Hierarchy

Input Side

Reader
 ├── FileReader
 ├── BufferedReader
 ├── InputStreamReader
 └── CharArrayReader
          

Output Side

Writer
 ├── FileWriter
 ├── BufferedWriter
 ├── OutputStreamWriter
 └── PrintWriter
          

Reader (Base Class)

Used to read characters.

Key Methods

int read();            // reads one character
int read(char[] c);    // reads multiple characters
void close();          // closes stream
✔ Returns -1 at end of stream
          

Writer (Base Class)

Used to write characters.

Key Methods

void write(int c);           // writes one character
void write(char[] c);        // writes char array
void write(String s);        // writes string
void flush();
void close();
          

FileReader (Reading Text Files)

FileReader fr = new FileReader("data.txt");
int ch;
while ((ch = fr.read()) != -1) {
    System.out.print((char) ch);
}
fr.close();
          
  • ✔ Reads character by character
  • ❌ No buffering → slower

FileWriter (Writing Text Files)

FileWriter fw = new FileWriter("output.txt");
fw.write("Hello Java");
fw.close();
          
  • ✔ Overwrites by default
  • ✔ Append mode available
FileWriter fw = new FileWriter("output.txt", true);
          

Buffered Character Streams (Recommended)

BufferedReader

  • Reads text efficiently
  • Supports line-by-line reading
BufferedReader br =
    new BufferedReader(new FileReader("data.txt"));
String line;
while ((line = br.readLine()) != null) {
    System.out.println(line);
}
br.close();
          
  • ✔ Very fast
  • ✔ Most commonly used

BufferedWriter

  • Writes text efficiently
BufferedWriter bw =
    new BufferedWriter(new FileWriter("out.txt"));
bw.write("Java I/O");
bw.newLine();
bw.close();
          

InputStreamReader & OutputStreamWriter (Bridge Classes)

  • Convert byte streams to character streams
  • Handle explicit character encoding
InputStreamReader isr =
    new InputStreamReader(new FileInputStream("data.txt"), "UTF-8");
✔ Important for encoding control
          

Character Streams vs Byte Streams (Interview Favorite)

Aspect Character Streams Byte Streams
Data unit Character (16-bit) Byte (8-bit)
Encoding ✔ Yes ❌ No
File type Text Binary
Base classes Reader / Writer InputStream / OutputStream
Example Text files Images, PDFs

Common Beginner Mistakes

  • Using character streams for binary data
  • Ignoring encoding issues
  • Not using buffering
  • Forgetting to close streams
  • Hardcoding file paths

Best Practices

  • Use BufferedReader / BufferedWriter for text files
  • Use InputStreamReader for encoding control
  • Use try-with-resources
  • Prefer NIO (Files.readAllLines) for modern code
try (BufferedReader br = new BufferedReader(new FileReader("a.txt"))) {
    // read logic
}
          

Interview-Ready Answers

Short Answer

Character streams are used to read and write text data in Java.

Detailed Answer

In Java, character streams are based on Reader and Writer classes and are used for handling text data. They support Unicode characters and character encoding, making them suitable for reading and writing text files, unlike byte streams which handle raw binary data.

Key Takeaway

Character Streams = Text Data Handling. Use them for human-readable content, prefer buffering for performance, and manage encoding explicitly when required.

Practical Examples (FileWriter, FileReader, Buffered I/O)

1. Writing Text Using FileWriter

import java.io.*;

class Demo {
    public static void main(String[] args) throws Exception {
        FileWriter fw = new FileWriter("text.txt");
        fw.write("Hello Java");
        fw.close();
    }
}
          

Key Point

  • Writes characters, not bytes
  • Best for text files

2. Writing Multiple Lines

import java.io.*;

class Demo {
    public static void main(String[] args) throws Exception {
        FileWriter fw = new FileWriter("data.txt");
        fw.write("Java\n");
        fw.write("Selenium\n");
        fw.write("Testing");
        fw.close();
    }
}
          

3. Appending Text Using FileWriter

import java.io.*;

class Demo {
    public static void main(String[] args) throws Exception {
        FileWriter fw = new FileWriter("data.txt", true);
        fw.write("\nAppended Line");
        fw.close();
    }
}
          

Interview Trap

  • Default mode overwrites
  • Use true for append

4. Reading Text Using FileReader

import java.io.*;

class Demo {
    public static void main(String[] args) throws Exception {
        FileReader fr = new FileReader("text.txt");
        int ch;
        while ((ch = fr.read()) != -1) {
            System.out.print((char) ch);
        }
        fr.close();
    }
}
          

5. Reading Characters into Buffer

import java.io.*;

class Demo {
    public static void main(String[] args) throws Exception {
        FileReader fr = new FileReader("text.txt");
        char[] buffer = new char[50];
        int len = fr.read(buffer);
        System.out.println(new String(buffer, 0, len));
        fr.close();
    }
}
          

6. Using BufferedWriter (Best Practice)

import java.io.*;

class Demo {
    public static void main(String[] args) throws Exception {
        BufferedWriter bw =
            new BufferedWriter(new FileWriter("buffer.txt"));
        bw.write("Buffered Writing");
        bw.newLine();
        bw.write("Fast IO");
        bw.close();
    }
}
          

Why

  • Reduces disk I/O
  • Faster than FileWriter

7. Using BufferedReader (Line by Line)

import java.io.*;

class Demo {
    public static void main(String[] args) throws Exception {
        BufferedReader br =
            new BufferedReader(new FileReader("buffer.txt"));
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        br.close();
    }
}
          

8. Copying Text File (Character Stream Way)

import java.io.*;

class Demo {
    public static void main(String[] args) throws Exception {
        BufferedReader br =
            new BufferedReader(new FileReader("source.txt"));
        BufferedWriter bw =
            new BufferedWriter(new FileWriter("target.txt"));

        String line;
        while ((line = br.readLine()) != null) {
            bw.write(line);
            bw.newLine();
        }

        br.close();
        bw.close();
    }
}
          

9. Writing Characters Using write(char[])

import java.io.*;

class Demo {
    public static void main(String[] args) throws Exception {
        char[] data = {'J', 'a', 'v', 'a'};
        FileWriter fw = new FileWriter("chars.txt");
        fw.write(data);
        fw.close();
    }
}
          

10. Try-With-Resources (Recommended)

import java.io.*;

class Demo {
    public static void main(String[] args) throws Exception {
        try (BufferedReader br =
                 new BufferedReader(new FileReader("text.txt"))) {
            System.out.println(br.readLine());
        }
    }
}
          

Why

  • Auto-closes streams
  • Cleaner code

11. Character Streams Handle Unicode Properly

import java.io.*;

class Demo {
    public static void main(String[] args) throws Exception {
        FileWriter fw = new FileWriter("unicode.txt");
        fw.write("Java ❤️ Selenium");
        fw.close();
    }
}
          

12. Encoding Control Using InputStreamReader

import java.io.*;
import java.nio.charset.StandardCharsets;

class Demo {
    public static void main(String[] args) throws Exception {
        InputStreamReader isr =
            new InputStreamReader(
                new FileInputStream("text.txt"),
                StandardCharsets.UTF_8);
        BufferedReader br = new BufferedReader(isr);
        System.out.println(br.readLine());
        br.close();
    }
}
          

Interview Note

  • FileReader uses default charset
  • InputStreamReader gives explicit control

13. Writing with Encoding Using OutputStreamWriter

import java.io.*;
import java.nio.charset.StandardCharsets;

class Demo {
    public static void main(String[] args) throws Exception {
        OutputStreamWriter osw =
            new OutputStreamWriter(
                new FileOutputStream("utf8.txt"),
                StandardCharsets.UTF_8);
        osw.write("UTF-8 Content");
        osw.close();
    }
}
          

14. Common Interview Trap – Using Byte Stream for Text

FileInputStream fis = new FileInputStream("text.txt"); // ❌ not ideal
          

Correct

FileReader fr = new FileReader("text.txt");
          

15. Reading Entire File at Once (Java 11+)

import java.nio.file.*;

class Demo {
    public static void main(String[] args) throws Exception {
        String content = Files.readString(Path.of("text.txt"));
        System.out.println(content);
    }
}
          

16. Writing Entire Text at Once (Java 11+)

import java.nio.file.*;

class Demo {
    public static void main(String[] args) throws Exception {
        Files.writeString(Path.of("file.txt"), "Hello World");
    }
}
          

17. Character Stream vs Byte Stream (Code View)

FileReader / FileWriter   // text
FileInputStream / FileOutputStream // binary
          

18. Handling IOException

try (FileReader fr = new FileReader("missing.txt")) {
} catch (IOException e) {
    System.out.println("File error");
}
          

19. Real-World Use Case

  • Logs
  • Configuration files
  • Test data (CSV, TXT)

20. Interview Summary – Character Streams

Reader / Writer

Key Points

  • Designed for text data
  • Automatically handles characters
  • Buffered versions are faster
  • Encoding matters
  • Prefer BufferedReader/Writer in real apps