File I/O in Java: Reading and Writing Files
File input and output (I/O) is a fundamental skill for any programmer. Whether you are reading data from a CSV file, writing logs to a text file, or processing configuration files, understanding how to work with files in Java is essential. Java provides several classes for reading and writing files, from simple text files to complex binary formats. In this guide, we will cover the most common approaches to file I/O in Java.
Reading Files with Scanner
The Scanner class is one of the simplest ways to read files in Java. You can create a Scanner that reads from a File object: Scanner scanner = new Scanner(new File("data.txt")). The Scanner provides methods like nextLine() for reading entire lines, next() for reading individual words, and nextInt(), nextDouble() for reading specific data types. When you are done reading, you should close the Scanner to release the file handle.
One common pattern is reading a file line by line using a while loop: while (scanner.hasNextLine()) { String line = scanner.nextLine(); /* process line */ }. This pattern works for files of any size and is the most common way to process text files in Java.
Reading Files with BufferedReader
BufferedReader provides more efficient file reading than Scanner because it reads larger chunks of data at once. It is wrapped around a FileReader: BufferedReader reader = new BufferedReader(new FileReader("data.txt")). The readLine() method reads one line at a time, returning null when the end of the file is reached.
BufferedReader is faster than Scanner for large files because of its buffering. Scanner performs more processing on each line (parsing tokens, checking data types), while BufferedReader simply reads raw text. For simple line-by-line processing, BufferedReader is preferred. For reading specific data types from a file, Scanner is more convenient.
Writing Files with PrintWriter
PrintWriter is the simplest way to write text files in Java. You create a PrintWriter with a File object: PrintWriter writer = new PrintWriter(new File("output.txt")). The PrintWriter provides println(), print(), and printf() methods that work exactly like System.out. When you are done writing, you should close the PrintWriter to ensure all data is flushed to the file.
If you want to append to an existing file rather than overwriting it, you can pass a second argument to the constructor: new PrintWriter(new FileWriter("output.txt", true)). The true flag indicates append mode, which adds new content to the end of the file instead of replacing its contents.
Try-With-Resources
Java 7 introduced the try-with-resources statement, which automatically closes resources when they are no longer needed. This is particularly useful for file I/O, where forgetting to close a file can lead to resource leaks. With try-with-resources, you declare the resource in the try statement: try (Scanner scanner = new Scanner(new File("data.txt"))) { /* use scanner */ }. The scanner is automatically closed when the try block exits, even if an exception occurs.
Try-with-resources is the recommended way to handle file I/O in modern Java. It is cleaner and safer than manually closing resources in a finally block. All classes that implement the AutoCloseable interface can be used with try-with-resources, which includes Scanner, BufferedReader, PrintWriter, and many other I/O classes.
Handling File Exceptions
File operations can throw several types of exceptions. FileNotFoundException is thrown when the specified file does not exist. IOException is thrown when an I/O error occurs, such as a disk failure or permission problem. These are checked exceptions, which means the compiler requires you to handle them or declare them in the method signature.
A common pattern is to catch FileNotFoundException separately to provide a user-friendly message, and then let other IOExceptions propagate. You can also use a try-catch block to handle the exception gracefully: try { /* file operations */ } catch (FileNotFoundException e) { System.out.println("File not found: " + e.getMessage()); }. Always provide meaningful error messages when handling file exceptions.
File I/O on the AP CSA Exam
The AP CSA exam may test your understanding of file I/O concepts, though actual file operations are not typically required on the free-response questions. You should understand how to use Scanner to read from a file, how to use PrintWriter to write to a file, and how to handle the exceptions that file operations can throw. Understanding file I/O is also important for the Create Performance Task in AP CSP, where you may need to read or write data files.