Chapter 22: File I/O and Serialization
Almost every real-world Java application needs to
- read data from files (configuration, logs, user data, CSV, JSON…)
- write data to files (save game progress, generate reports, export data…)
- serialize objects (save them to disk, send over network)
- deserialize them back (read from disk, receive from network)
We will cover everything very slowly and thoroughly, step-by-step, with many complete, runnable examples.
Let’s start!
1. Classical File I/O (The traditional way – still very important)
These classes are located in package java.io
Most important classes you will use every day
| Class | What it does | Use when you want to… | Character / Byte |
|---|---|---|---|
| File | Represents file or directory path | Check exists, create, delete, get size… | — |
| FileReader | Read characters from file | Read text files character by character | Character |
| FileWriter | Write characters to file | Write text files | Character |
| BufferedReader | Read text efficiently line by line | Most common way to read text files | Character |
| BufferedWriter | Write text efficiently | Most common way to write text files | Character |
| FileInputStream | Read raw bytes | Images, videos, binary files | Byte |
| FileOutputStream | Write raw bytes | Images, videos, binary files | Byte |
Very Important Rule (Beginners always forget this!)
Always close files after you finish using them → Otherwise → file handles leak, program may crash when too many files are open → Best practice in 2025–2026 → use try-with-resources (automatic close!)
2. Reading Files – Most Common Ways
Way 1 – Classic BufferedReader + try-with-resources (Most Recommended)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import java.io.*; public class ReadFileClassic { public static void main(String[] args) { String filePath = "input.txt"; // change to your real path // try-with-resources → auto close! try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { String line; int lineNumber = 1; while ((line = br.readLine()) != null) { System.out.printf("Line %2d : %s%n", lineNumber++, line); } } catch (FileNotFoundException e) { System.out.println("File not found: " + filePath); } catch (IOException e) { System.out.println("Error reading file: " + e.getMessage()); } } } |
Way 2 – Read all lines at once (very convenient – Java 8+)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import java.nio.file.*; import java.util.List; public class ReadAllLines { public static void main(String[] args) { try { List<String> allLines = Files.readAllLines(Paths.get("input.txt")); for (int i = 0; i < allLines.size(); i++) { System.out.printf("Line %2d : %s%n", i+1, allLines.get(i)); } } catch (IOException e) { System.out.println("Error: " + e.getMessage()); } } } |
3. Writing Files – Most Common Ways
Way 1 – BufferedWriter + try-with-resources (Most Recommended)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import java.io.*; public class WriteFileClassic { public static void main(String[] args) { String filePath = "output.txt"; try (BufferedWriter bw = new BufferedWriter(new FileWriter(filePath))) { bw.write("Hello Webliance!\n"); bw.write("This is line 2\n"); bw.write("Current year: 2026\n"); // You can also write formatted bw.write(String.format("Score: %d / 100%n", 95)); System.out.println("File written successfully!"); } catch (IOException e) { System.out.println("Error writing file: " + e.getMessage()); } } } |
Way 2 – Write all lines at once (very clean – Java 8+)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import java.nio.file.*; import java.util.*; public class WriteAllLines { public static void main(String[] args) { List<String> lines = Arrays.asList( "First line", "Second line", "Third line - 2026", String.format("Score: %d%%", 98) ); try { Files.write(Paths.get("output.txt"), lines); // or append mode: // Files.write(Paths.get("output.txt"), lines, StandardOpenOption.APPEND); System.out.println("Successfully written!"); } catch (IOException e) { System.out.println("Error: " + e.getMessage()); } } } |
4. Modern Way – NIO.2 (java.nio.file) → Recommended in 2025–2026
NIO.2 (Non-blocking I/O) is more powerful, cleaner, and more modern
Most important classes:
| Class | Purpose | Most used methods |
|---|---|---|
| Path | Represents file/folder path | Paths.get(“file.txt”) |
| Files | Static utility class – almost everything | readAllLines(), write(), exists(), createFile(), size()… |
Very common NIO.2 patterns
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
import java.nio.file.*; import java.util.*; public class NioDemo { public static void main(String[] args) { Path path = Paths.get("data.txt"); // 1. Check if file exists if (Files.exists(path)) { System.out.println("File size: " + Files.size(path) + " bytes"); } // 2. Read all lines try { List<String> lines = Files.readAllLines(path); lines.forEach(System.out::println); } catch (IOException e) { System.out.println("Cannot read: " + e.getMessage()); } // 3. Write – StandardOpenOption.APPEND / CREATE / CREATE_NEW List<String> newContent = Arrays.asList( "New line 1", "New line 2 - " + java.time.LocalDate.now() ); try { Files.write(path, newContent, StandardOpenOption.APPEND); System.out.println("Appended successfully!"); } catch (IOException e) { System.out.println("Write error: " + e.getMessage()); } } } |
5. Serialization & Deserialization (Saving & Loading Objects)
Serialization = converting object → stream of bytes (save to file, send over network) Deserialization = converting bytes → object back
Important Rules:
- Class must implement java.io.Serializable
- All fields that should be saved must be Serializable too (or marked transient)
- static fields are not serialized
Example – Full Serialization / Deserialization
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
import java.io.*; // Must implement Serializable class Student implements Serializable { private static final long serialVersionUID = 1L; // very important! private String name; private int age; private transient double gpa; // will NOT be saved public Student(String name, int age, double gpa) { this.name = name; this.age = age; this.gpa = gpa; } @Override public String toString() { return "Student{name='" + name + "', age=" + age + ", gpa=" + gpa + "}"; } } public class SerializationDemo { public static void main(String[] args) { String fileName = "student.ser"; // 1. Serialize (Save) try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName))) { Student s1 = new Student("Webliance", 25, 9.8); Student s2 = new Student("Priya", 23, 9.2); oos.writeObject(s1); oos.writeObject(s2); System.out.println("Objects saved!"); } catch (IOException e) { e.printStackTrace(); } // 2. Deserialize (Load) try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName))) { Student loaded1 = (Student) ois.readObject(); Student loaded2 = (Student) ois.readObject(); System.out.println("Loaded 1: " + loaded1); System.out.println("Loaded 2: " + loaded2); // Note: gpa will be 0.0 because it was transient } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } } |
Quick Summary Table
| Task | Recommended Modern Way (2025–2026) | Classical Way (still okay) |
|---|---|---|
| Read text file line by line | Files.readAllLines() or Files.lines() | BufferedReader + readLine() |
| Write text file | Files.write() | BufferedWriter |
| Append to file | Files.write(…, StandardOpenOption.APPEND) | new FileWriter(path, true) |
| Save whole object to file | ObjectOutputStream + Serializable | Same |
| Most safe & clean way | Always use try-with-resources | — |
Homework for You (Very Practical!)
- Basic Create a program that reads a text file line by line and prints only lines that contain word “java” (case insensitive)
- Medium Write a program that reads numbers from file numbers.txt (one number per line) → calculates sum, average, min, max
- Advanced Create a small Contact class (name, phone, email) → implement Serializable → save 5 contacts to file → read them back and print
- Fun Make a program that appends current timestamp + random message to a log file every time it runs
- Challenge Try to serialize a class that contains another object → see what happens if inner object is not Serializable
You are doing amazing! File I/O + Serialization is one of the most frequently used skills in real Java jobs.
