Writing Files
IB Syllabus: B2.5.1 – Construct code to perform file-processing operations: open files in write/append mode, write to files, close files.
Key Concepts
Writing with FileWriter
FileWriter writes text to a file. By default, it overwrites any existing content.
import java.io.FileWriter;
import java.io.IOException;
try {
FileWriter writer = new FileWriter("output.txt");
writer.write("Alice,85\n");
writer.write("Bob,72\n");
writer.write("Charlie,91\n");
writer.close();
System.out.println("File written successfully.");
} catch (IOException e) {
System.out.println("Error writing file: " + e.getMessage());
}
try:
f = open("output.txt", "w") # "w" = write mode - overwrites existing content
f.write("Alice,85\n")
f.write("Bob,72\n")
f.write("Charlie,91\n")
f.close()
print("File written successfully.")
except OSError: # OSError is Python's IOException - raised when writing fails
print("Error writing file.")
Always call writer.close(). Without closing, data may remain in a buffer and never reach the file on disk.
Overwrite vs Append
| Mode | Constructor | Behaviour |
|---|---|---|
| Overwrite | new FileWriter("file.txt") | Erases existing content, starts fresh |
| Append | new FileWriter("file.txt", true) | Adds to end of existing content |
(Python: overwrite is open("file.txt", "w"), append is open("file.txt", "a") - the mode string does the job of Java’s extra argument.)
// Append mode -- adds to end of file
FileWriter writer = new FileWriter("log.txt", true);
writer.write("New entry added.\n");
writer.close();
# Append mode - "a" adds to the end of the file
f = open("log.txt", "a")
f.write("New entry added.\n")
f.close()
Use overwrite when saving the complete current state (e.g., saving all records). Use append when adding to a log or history.
Writing with BufferedWriter
BufferedWriter wraps FileWriter for better efficiency and adds the newLine() method.
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("results.txt"));
writer.write("Name,Score");
writer.newLine();
writer.write("Alice,85");
writer.newLine();
writer.write("Bob,72");
writer.newLine();
writer.close();
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
# Python has no separate BufferedWriter - open() already buffers writes.
# There is no newLine() either: write "\n" yourself (write() adds nothing automatically).
try:
f = open("results.txt", "w")
f.write("Name,Score\n")
f.write("Alice,85\n")
f.write("Bob,72\n")
f.close()
except OSError:
print("Error writing file.")
newLine() inserts the correct line separator for the operating system (Windows: \r\n, macOS/Linux: \n). This is more portable than hardcoding "\n".
try-with-resources
The cleanest approach – automatically closes the writer:
try (BufferedWriter writer = new BufferedWriter(new FileWriter("data.csv"))) {
writer.write("Alice,85");
writer.newLine();
writer.write("Bob,72");
writer.newLine();
} // writer is automatically closed here
(Python has a similar shortcut, the with statement, but IB Python uses explicit open() and close() - so we do too.)
Worked Examples
Example 1: Save an ArrayList to a File
public static void saveNames(ArrayList<String> names, String filename)
throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
for (int i = 0; i < names.size(); i++) {
writer.write(names.get(i));
writer.newLine();
}
writer.close();
}
def save_names(names, filename):
f = open(filename, "w")
for i in range(len(names)):
f.write(names[i] + "\n")
f.close()
Example 2: Write CSV Data
Save structured data with comma-separated fields.
public static void saveStudents(ArrayList<Student> students, String filename)
throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
for (int i = 0; i < students.size(); i++) {
Student s = students.get(i);
writer.write(s.getName() + "," + s.getGrade());
writer.newLine();
}
writer.close();
}
def save_students(students, filename):
f = open(filename, "w")
for i in range(len(students)):
s = students[i]
f.write(s.get_name() + "," + str(s.get_grade()) + "\n") # str() needed - Python will not join a number onto a string automatically
f.close()
Example 3: Append a Log Entry
public static void logAction(String action, String filename)
throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(filename, true));
writer.write(action);
writer.newLine();
writer.close();
}
def log_action(action, filename):
f = open(filename, "a") # "a" = append mode
f.write(action + "\n")
f.close()
Example 4: Complete Read-Process-Write Pipeline
Read scores, calculate the average, and write a summary file.
import java.util.*;
import java.io.*;
public class ScoreSummary {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
ArrayList<Integer> scores = new ArrayList<>();
// READ
try (Scanner reader = new Scanner(new File("students.csv"))) {
while (reader.hasNextLine()) {
String[] parts = reader.nextLine().split(",");
names.add(parts[0].trim());
scores.add(Integer.parseInt(parts[1].trim()));
}
} catch (FileNotFoundException e) {
System.out.println("Input file not found.");
return;
}
// PROCESS
int total = 0;
for (int i = 0; i < scores.size(); i++) {
total += scores.get(i);
}
double average = (scores.size() > 0) ? (double) total / scores.size() : 0;
// WRITE
try (BufferedWriter writer = new BufferedWriter(new FileWriter("summary.txt"))) {
writer.write("Student Score Summary");
writer.newLine();
writer.write("=====================");
writer.newLine();
for (int i = 0; i < names.size(); i++) {
writer.write(names.get(i) + ": " + scores.get(i));
writer.newLine();
}
writer.write("---------------------");
writer.newLine();
writer.write("Average: " + average);
writer.newLine();
} catch (IOException e) {
System.out.println("Error writing summary: " + e.getMessage());
}
System.out.println("Summary written to summary.txt");
}
}
# main() is a function here so that "return" can stop the program early,
# exactly like Java's return inside main.
def main():
names = []
scores = []
# READ
try:
f = open("students.csv", "r")
line = f.readline()
while line != "":
parts = line.split(",")
names.append(parts[0].strip())
scores.append(int(parts[1].strip()))
line = f.readline()
f.close()
except FileNotFoundError:
print("Input file not found.")
return # stop - there is nothing to process
# PROCESS
total = 0
for i in range(len(scores)):
total = total + scores[i]
if len(scores) > 0:
average = total / len(scores)
else:
average = 0
# WRITE
try:
f = open("summary.txt", "w")
f.write("Student Score Summary\n")
f.write("=====================\n")
for i in range(len(names)):
f.write(names[i] + ": " + str(scores[i]) + "\n")
f.write("---------------------\n")
f.write("Average: " + str(average) + "\n")
f.close()
except OSError:
print("Error writing summary.")
print("Summary written to summary.txt")
main()
Quick Check
Q1. What happens to existing content when you use new FileWriter("data.txt")?
Q2. How do you open a file in append mode?
Q3. What does writer.newLine() do?
Q4. What can happen if you forget to call writer.close()?
Q5. Which exception should you catch when writing to a file?
Code Completion
Complete the method that saves student names and grades to a CSV file.
Fill in the blanks: Save each student as a CSV line.
public static void save(ArrayList<Student> students, String filename)
throws IOException {
BufferedWriter writer = new BufferedWriter(new (filename));
for (int i = 0; i < students.size(); i++) {
Student s = students.get(i);
writer.(s.getName() + "," + s.getGrade());
writer.;
}
writer.;
} Spot the Error
This code should append a new score to a file, but it erases everything each time.
Bug Hunt: Every time this method runs, previous scores disappear and only the latest score remains.
Pick the correct fix for line 2:
Predict the Output
Predict: What does the file test.txt contain after this code runs?
FileWriter writer = new FileWriter("test.txt");
writer.write("Hello");
writer.write("World");
writer.close();
Scanner reader = new Scanner(new File("test.txt"));
System.out.println(reader.nextLine());
reader.close(); Practice Exercises
Core
-
Write five names – Ask the user for five names (via Scanner on keyboard) and write them to
names.txt, one per line. -
Append mode test – Modify exercise 1 to use append mode. Run it twice and verify the file contains 10 names.
-
Copy uppercase – Read all lines from
input.txtand write them tooutput.txtwith each line converted to uppercase using.toUpperCase().
Extension
-
CSV report – Read
students.csv(name,score), calculate the average, and write a formatted report toreport.txtlisting each student, their score, and whether they are above or below average. -
Log with timestamps – Write a method
log(String message)that appends a line tolog.txtin the format[YYYY-MM-DD HH:MM:SS] message. Usejava.time.LocalDateTime.now().
Challenge
- File-based address book – Build a complete program that stores contacts (name, phone, email) in a CSV file. Support four operations: add a contact (append), list all contacts (read + display), search by name (read + filter), and delete by name (read all, write back without the match). The file is the only storage – no data is kept in memory between operations.
Connections
- Prerequisites: Reading Files – reading is the counterpart to writing
- Prerequisites: Exception Handling – try/catch for IOExceptions
- Related: ArrayList – saving ArrayList contents to files
- Forward: File I/O in Apps – file I/O integrated into MVC applications