Java Notes
Complete guide to Character Streams in Java — FileReader, FileWriter, handling Unicode text, character encoding, reading/writing text files with proper internationalization support.
What are Character Streams?
Character streams handle I/O of character (text) data. They automatically handle the translation between bytes and characters using a character encoding (like UTF-8, UTF-16).
Why Not Just Use Byte Streams for Text?
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
| Original text | Hello 日本語 العربية 한국어 |
| UTF-8 bytes | 37 bytes |
| UTF-16 bytes | 44 bytes |
| Characters | 20 chars |
| Read back | Hello 日本語 العربية 한국어 |
Character Stream Hierarchy
FileWriter — Writing Text
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
FileReader — Reading Text
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
| Chunk 1 (20 chars) | 'Roses are red,\nViole' |
| Chunk 2 (20 chars) | 'ts are blue,\nJava is' |
| Chunk 3 (20 chars) | ' awesome,\nAnd so are' |
| Chunk 4 (8 chars) | ' you!\n' |
Character Encoding with InputStreamReader / OutputStreamWriter
FileReader and FileWriter use the system's default encoding. For explicit encoding control, use the bridge classes:
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
| Text | Héllo Wörld! 你好世界 🌍 |
| Read UTF-8 | Héllo Wörld! 你好世界 🌍 |
| Encoding used | UTF8 |
| Read Latin-1 | H?llo W?rld! ???? ?? |
| UTF-8 | 29 bytes |
| Latin-1 | 19 bytes |
PrintWriter — Convenient Text Output
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
Real-World Example: CSV File Handler
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Output:
Byte Stream vs Character Stream Comparison
Try it in WoHoCode
Edit the program, then run it here.
Run this example to see its output.
Common Mistakes
1. Using FileReader/FileWriter for binary files
// ❌ WRONG: Will corrupt binary data (images, PDFs, etc.)
FileReader reader = new FileReader("image.png");
// ✅ CORRECT: Use byte streams for binary
FileInputStream fis = new FileInputStream("image.png");2. Ignoring character encoding
// ❌ BAD: Uses platform default encoding (unpredictable)
FileWriter writer = new FileWriter("data.txt");
// ✅ GOOD: Specify encoding explicitly
OutputStreamWriter writer = new OutputStreamWriter(
new FileOutputStream("data.txt"), StandardCharsets.UTF_8);
// ✅ BETTER (Java 11+):
Files.writeString(Path.of("data.txt"), content, StandardCharsets.UTF_8);3. Not flushing before close
// ✅ Try-with-resources handles this automatically
try (FileWriter writer = new FileWriter("file.txt")) {
writer.write("data");
} // flush + close called automaticallyInterview Questions
Q1: What is the difference between byte stream and character stream?
Answer: Byte streams (InputStream/OutputStream) work with raw bytes (8-bit) and are suitable for all file types. Character streams (Reader/Writer) work with characters (16-bit Unicode) and handle encoding/decoding automatically, making them ideal for text processing.
Q2: What is InputStreamReader? Why is it called a "bridge"?
Answer: InputStreamReader converts a byte stream (InputStream) into a character stream (Reader). It's called a bridge because it connects the two stream hierarchies, reading bytes from the underlying InputStream and decoding them into characters using a specified charset.
Q3: What encoding does FileReader use by default?
Answer: It uses the platform's default charset (e.g., UTF-8 on Linux, Cp1252 on Windows). Since Java 18, the default is UTF-8 on all platforms. For portability, always specify encoding explicitly using InputStreamReader with a charset.
Q4: Can FileWriter handle Unicode characters like Chinese or emoji?
Answer: Yes, if the file's encoding supports them. FileWriter uses the platform's default encoding. If that's UTF-8, it handles all Unicode. But on some Windows systems with default Latin-1 encoding, non-Latin characters will be corrupted. Always specify UTF-8 explicitly for international text.
Q5: Why should you prefer BufferedReader over FileReader directly?
Answer: FileReader reads from disk one character at a time (one system call per read). BufferedReader wraps FileReader with an internal buffer (default 8KB), dramatically reducing disk I/O. It also provides readLine() method for line-by-line reading.
Continue the lesson path