13.1 The File Class — Metadata, Not Contents
java.io.File represents a path (file or directory) and manipulates metadata only — it never reads contents:
File f = new File("notes.txt");
f.exists(); f.length(); f.isDirectory(); f.getAbsolutePath();
f.createNewFile(); f.delete(); f.renameTo(dest);
new File("reports/2025").mkdirs(); // create nested dirs
for (String name : new File(".").list()) System.out.println(name);
13.2 Byte Streams vs Character Streams
| Aspect | Byte streams | Character streams |
|---|---|---|
| Base classes | InputStream / OutputStream | Reader / Writer |
| Unit | 8-bit bytes | 16-bit chars (charset-decoded) |
| For | Images, audio, PDFs, ZIPs — any binary | Text (handles UTF-8 etc. correctly) |
| Key concrete types | FileInputStream, FileOutputStream | FileReader, FileWriter |
| Buffered wrappers | BufferedInputStream/OutputStream | BufferedReader/Writer |
| Bridge classes | — | InputStreamReader / OutputStreamWriter |
Java I/O uses the Decorator pattern: wrap streams inside streams — new BufferedReader(new InputStreamReader(System.in)) was the standard console-input idiom before Scanner. Reading text through byte streams corrupts multi-byte UTF-8 characters — the classic "why character streams exist" answer.
13.3 Buffered Text I/O — The Workhorse Pattern
try (BufferedReader br = new BufferedReader(new FileReader("in.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt", true))) { // true = append
String line;
while ((line = br.readLine()) != null) { // null signals EOF
bw.write(line.toUpperCase());
bw.newLine(); // platform-correct line ending
}
} // both closed automatically, reverse order
Buffering batches disk hits (default 8 KB buffer) — orders of magnitude faster than unbuffered per-char reads. readLine() returns null at EOF (not an exception). flush() pushes buffered bytes out; close() flushes then releases the OS handle. Also know PrintWriter (printf-style convenience, never throws IOException — check checkError()).
13.4 Serialization — Objects to Bytes
Serialization converts an object graph into a byte stream (file, socket, cache); deserialization rebuilds it.
class Account implements Serializable { // marker interface!
private static final long serialVersionUID = 1L; // version stamp
String owner;
transient String password; // excluded from the stream
static int branchCode = 7; // static: never serialized
}
try (var oos = new ObjectOutputStream(new FileOutputStream("acc.ser"))) {
oos.writeObject(acct);
}
try (var ois = new ObjectInputStream(new FileInputStream("acc.ser"))) {
Account back = (Account) ois.readObject(); // cast + ClassNotFoundException
} // back.password == null, branchCode from the CLASS, not the stream
Must-know rules: the class implements Serializable or NotSerializableException is thrown; transient fields deserialize to defaults; static fields belong to the class, not the object, so they are skipped; every non-transient field's type must itself be serializable; serialVersionUID guards version compatibility — omit it and any recompile can make old files unreadable (InvalidClassException); parent-class state is serialized only if the parent is also Serializable, otherwise its no-arg constructor runs on read.
13.5 NIO.2 Glance — Path & Files (Java 7+)
Path p = Paths.get("data", "log.txt");
Files.writeString(p, "hello"); // one-liners (Java 11)
String s = Files.readString(p);
List<String> lines = Files.readAllLines(p);
Files.copy(p, Paths.get("backup.txt"), StandardCopyOption.REPLACE_EXISTING);
try (Stream<String> st = Files.lines(p)) { st.filter(l -> l.contains("ERROR")).forEach(System.out::println); }
NIO adds buffers + channels (non-blocking I/O), DirectoryStream, WatchService, and rich metadata — for this course, know Path/Files one-liners and that NIO is the modern replacement for most File juggling.
🎯 Exam Focus
- Differentiate byte streams and character streams, naming the four abstract base classes and one concrete class each.
- Explain the roles of BufferedReader and BufferedWriter. Why is buffering faster? Write a program to copy a text file line by line.
- What is serialization? Explain Serializable, serialVersionUID, and the effect of
transientandstaticon serialized state. - Write a program to serialize a Student object to student.ser and read it back, printing the restored state.
- How does try-with-resources improve I/O code? What happens to the file handle if an exception occurs mid-read?
- Give NIO.2 equivalents (Path/Files) for reading all lines and copying a file.