Teacher Guide: File Processing
Student page: File Processing IB Syllabus: B2.5 Suggested timing: 1–2 periods (90 min each)
Contents
Lesson Plans
Period 1: Reading and Writing Files (90 min)
| Phase | Time | Activity | Notes |
|---|---|---|---|
| Warm-up | 10 min | “What happens to all your program’s data when it finishes?” — persistence motivation | Students list 5 programs that need persistence |
| Teach | 25 min | Scanner(new File(…)), hasNextLine() loop, FileWriter (overwrite vs append) | Draw pipeline: Disk → File → Scanner → Variable |
| Practice | 40 min | Read a text file and count lines, write user input to a file, append mode demo | |
| Wrap-up | 15 min | “What can go wrong?” — brainstorm failure modes before seeing exception code |
Teaching notes:
- Key insight: Scanner works the same for keyboard and file — only the constructor argument changes
- Overwrite vs append:
new FileWriter("f.txt")vsnew FileWriter("f.txt", true) - Always close demo: comment out
close(), show inconsistent results
Period 2: BufferedReader + Exception Handling (90 min)
| Phase | Time | Activity | Notes |
|---|---|---|---|
| Warm-up | 10 min | “For a 100,000-line log file, does Scanner vs BufferedReader matter?” | Bulk buying analogy |
| Teach | 20 min | BufferedReader, readLine() != null idiom, declare-outside/open-inside/close-in-finally | |
| Practice | 45 min | BufferedReader exercises, try-catch-finally pattern with file I/O | |
| Wrap-up | 15 min | End-to-end exercise: read numbers from file → process → write results to new file |
Differentiation
Supporting weaker students
| Strategy | When to use | Example |
|---|---|---|
| Scanner-only focus | Overwhelmed by BufferedReader | “BufferedReader is optional — Scanner works perfectly for exam-sized files” |
| File I/O template | Can’t remember the pattern | Provide skeleton: Scanner → while(hasNextLine) → process → close |
| Pipeline diagram | Can’t visualize file flow | Draw: Hard drive → File object → Scanner/Reader → String variable |
| One direction first | Confuses read vs write | Master reading completely before introducing writing |
Extending stronger students
| Strategy | When to use | Example |
|---|---|---|
| CSV parser | Finishes basic exercises | Read CSV file, split each line, store in 2D array — connects to data structures |
| try-with-resources | After finally pattern | “Java 7 introduced a cleaner way…” — show try (Scanner s = new Scanner(...)) { } |
| Log file analyser | After both read and write | Read a web server log, count errors, write summary report |
| File comparison | After mastering both | Read two files, report differences line by line |
Teaching Sequence
Why files? Persistence motivation
Before any code: Ask students what happens to all the data in their program when it finishes running. (It disappears.) Ask: “Name five real programs that would be useless if they lost all data when closed.” Students list: contact apps, games (high scores), bank apps, email, word processors.
This motivates the concept of persistence — data that outlasts the program — before they see a single line of file code.
Reading a file (B2.5.1)
Draw the pipeline first:
On the board, draw: Hard drive → File → Scanner → Variable. Label each arrow with what is happening: “disk read”, “wrap in Scanner”, “nextLine() / nextInt()”.
Then reveal the key insight: Scanner works the same way whether the source is the keyboard or a file. The only difference is what you pass to the constructor:
new Scanner(System.in) // keyboard
new Scanner(new File(...)) // file
This makes file reading feel like an extension of what they already know, not a new topic.
hasNextLine() loop pattern: Explain that unlike reading from the keyboard (where you know how many inputs to expect), a file may have any number of lines. hasNextLine() returning false is the signal that the file is exhausted. Ask: “What does the while condition become false? When there are no more lines.”
Writing to a file (B2.5.2)
Overwrite vs append — Notepad analogy:
Ask: “If you open a text file in Notepad, start typing, and save — what happens to what was already in the file?” (It is replaced.) “What if you wanted to add to the end instead of replacing?” That is exactly the true flag in FileWriter.
| Mode | Java | What happens |
|---|---|---|
| Overwrite | new FileWriter("f.txt") | File starts empty |
| Append | new FileWriter("f.txt", true) | New content added to end |
Ask when each mode is appropriate: overwrite for generating a fresh report; append for a log file that accumulates entries over time.
Always close: Write a program that writes to a file but comment out close(). Run it and check the file — sometimes the data is there, sometimes it is not (depends on buffer state). The inconsistency makes close() non-optional rather than a stylistic choice.
BufferedReader vs Scanner (B2.5.1)
Analogy — bulk buying vs one item at a time:
Scanner reads one character/token at a time from disk. BufferedReader fills a large memory buffer from disk in one operation, then serves your code from memory. This reduces the number of slow disk accesses dramatically.
Ask: “For a 10-line file, does it matter?” (No, negligible.) “For a 100,000-line log file?” (Yes, significantly.) BufferedReader is the professional choice for any non-trivial file.
The readLine() != null idiom:
while ((line = reader.readLine()) != null)
This does two things: reads the next line AND checks if it was null (end-of-file). Students find this confusing at first. Break it down: “What does readLine() return when there are no more lines?” (null.) “So the loop runs as long as what we read is not null.”
Exception handling in file operations (B2.5.3)
Enumerate failure modes first:
Before showing code, ask: “What can go wrong when your program tries to open a file?” Students should list:
- The file doesn’t exist (
FileNotFoundException) - No read/write permission (
IOException) - The disk is full (write operations)
- The file is locked by another process
Each maps to a specific exception. FileNotFoundException extends IOException — you can catch either, but catching the specific one is better practice.
The declare-outside, open-inside, close-in-finally pattern:
Walk through why the reader must be declared outside the try block:
BufferedReader reader = null; // declared outside — visible in finally
try {
reader = new BufferedReader(...); // opened inside
...
} finally {
if (reader != null) reader.close(); // closed in finally — always runs
}
Ask: “What if we declared reader inside the try block and an exception occurred before close()?” The reader variable would be out of scope in finally. This makes the pattern feel logical rather than arbitrary.
Common Student Mistakes
| Mistake | Description |
|---|---|
Forgetting close() | Data may not flush to disk — some content could be lost |
Reader declared inside try | Cannot close it in finally — resource leak if exception occurs |
Catching Exception only | Masks the specific error; should catch FileNotFoundException then IOException |
FileWriter without catching IOException | FileWriter constructor throws IOException — compile error if uncaught |
hasNextLine() vs hasNext() | hasNextLine() checks for a full line; hasNext() checks for a token; easy to mix up |
| Not handling FileNotFoundException separately | Treating “file not found” the same as a read error loses useful diagnostic information |
IB Paper 2 Exam Tips
- B2.5 is relatively accessible marks in Paper 2 — the patterns are few and well-defined. Students who practise the three patterns (read, write, append) reliably can score these marks.
- Know the three classes:
Scanner(new File(...)),FileWriter,BufferedReader. - Know the two
FileWritermodes: default (overwrite),true(append). - Exception handling is always required around file operations — a code-writing question that omits try/catch loses marks.
finallyalways runs — this is tested explicitly. “What is the purpose of the finally block in file processing?” → ensures the file is closed regardless of whether an exception occurred.hasNextLine()returnsfalseat end of file — the while loop terminates naturally, no explicit check needed.