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.
Table of Contents
- Key Concepts
- Worked Examples
- Quick Check
- Code Completion
- Spot the Error
- Predict the Output
- Practice Exercises
- Connections
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());
}
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 |
// Append mode -- adds to end of file
FileWriter writer = new FileWriter("log.txt", true);
writer.write("New entry added.\n");
writer.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());
}
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
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();
}
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();
}
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();
}
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");
}
}
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