Getting Started
So far, our programs have worked with data that we either type in manually or define directly in the code. To build more powerful and flexible applications, we need a way to read data that is stored permanently outside of our program. Java provides tools to connect to external text files, read their contents, and use that data to drive our program's logic.
What You Should Be Able to Do
Instantiate
ScannerandFileobjects to open a text file for reading.Use a
whileloop withhasNext()methods to process all the data in a file.Select the correct
Scannermethod to read data as a line, a word, an integer, or a double.Add a
throwsclause to a method signature to handle theFileNotFoundException.
Key Concepts & Java Implementation
The Core Idea
Programs often need to process data sets that are too large to type in each time the program runs, such as a list of high scores, configuration settings, or student records. Storing this data in a text file (.txt) allows it to persist even when the program is not running.
To read from a file in Java, we use two main classes. First, the java.io.File class is used to create an object that represents the path to the file on the computer's storage. Second, the java.util.Scanner class, which we've used for keyboard input, can be "attached" to a File object to read its contents. The Scanner treats the file's content as a stream of characters that it can process token by token or line by line.
Because the specified file might not exist at the given path, Java anticipates a potential error: the FileNotFoundException. This is a checked exception, meaning the compiler requires us to acknowledge that this error might happen. The standard way to do this in this course is by adding throws FileNotFoundException to the signature of any method that attempts to open a file.
Syntax & Implementation
To use these classes, you must first include them in your program with import statements.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
The general process involves creating a File object and passing it to the Scanner's constructor.
Syntax Table
| Construct / Clause | Purpose | Java Example |
|---|---|---|
new File(path) | Creates an object representing a file at a specific string path. | File dataFile = new File("scores.txt"); |
new Scanner(file) | Creates a scanner to read from the specified File object. | Scanner fileReader = new Scanner(dataFile); |
throws FileNotFoundException | Declares that a method might fail if the file is not found, satisfying the compiler. | public void readScores() throws FileNotFoundException |
Annotated Java Example 1: Reading a File Line by Line
Imagine a file named names.txt with the following content:
Alice
Bob
Charlie
This Java code reads each name and prints it.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class NameReader {
public void printNames() throws FileNotFoundException {
// 1. Create a File object that points to names.txt
File nameFile = new File("names.txt");
// 2. Create a Scanner to read from that file
Scanner in = new Scanner(nameFile);
// 3. Loop as long as there is another line to read
while (in.hasNextLine()) {
// 4. Read the next full line and store it
String name = in.nextLine();
// 5. Process the data (in this case, print it)
System.out.println("Hello, " + name);
}
// The Scanner is automatically closed when the method ends
}
}
Annotated Java Example 2: Reading Numerical Data
Imagine a file named grades.txt with the following content:
95.5 87.0 72.5
100.0 91.5
This Java code reads each grade and calculates the average.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class GradeCalculator {
public double getAverage() throws FileNotFoundException {
File gradeFile = new File("grades.txt");
Scanner in = new Scanner(gradeFile);
double sum = 0.0;
int count = 0;
// Loop as long as there is another double value to read
while (in.hasNextDouble()) {
// Read the next token that can be interpreted as a double
double grade = in.nextDouble();
sum += grade;
count++;
}
if (count == 0) {
return 0.0;
}
return sum / count;
}
}
Tracing & Analysis
Let's trace the execution of the getAverage method with the grades.txt file.
File Content:95.5 87.0 72.5 100.0 91.5
| Iteration | in.hasNextDouble() | grade | sum | count |
|---|---|---|---|---|
| Before Loop | true | (not initialized) | 0.0 | 0 |
| 1 | true | 95.5 | 95.5 | 1 |
| 2 | true | 87.0 | 182.5 | 2 |
| 3 | true | 72.5 | 255.0 | 3 |
| 4 | true | 100.0 | 355.0 | 4 |
| 5 | false | 91.5 | 446.5 | 5 |
| After Loop | false | 91.5 | 446.5 | 5 |
The loop terminates because after reading 91.5, in.hasNextDouble() returns false as there are no more numbers. The method then returns 446.5 / 5, which is 89.3.
Analysis: next() vs. nextLine()
A common point of confusion is the difference between Scanner methods that read tokens (like next(), nextInt()) and those that read lines (nextLine()).
next(),nextInt(),nextDouble(): These methods read the next "token," which is a sequence of characters separated by whitespace (spaces, tabs, newlines). They leave the cursor right after the token they read.nextLine(): This method reads all characters from the current cursor position until it finds a newline character (\n), and then it consumes the newline character.
Mixing these can cause problems. If you call nextInt() to read a number and then immediately call nextLine(), the nextLine() call will read the rest of the (often empty) line where the number was, not the next line of text.
Java Syntax Quick-Reference
import java.io.File;: Makes theFileclass available for use.import java.io.FileNotFoundException;: Makes the exception class available for thethrowsclause.import java.util.Scanner;: Makes theScannerclass available for use.new File(String path): Creates an object representing the file located at the given path.new Scanner(File fileObject): Creates aScannerthat reads from the specifiedFileobject.throws FileNotFoundException: A clause added to a method signature to declare that the method might fail if a file is not found at runtime..hasNext(): Returnstrueif the scanner has another token in its input..next(): Reads and returns the next token from the scanner as aString..hasNextLine(): Returnstrueif there is another line of input..nextLine(): Reads from the current position to the end of the line and returns it as aString..hasNextInt(): Returnstrueif the next token can be interpreted as anint..nextInt(): Reads and returns the next token as anint..hasNextDouble(): Returnstrueif the next token can be interpreted as adouble..nextDouble(): Reads and returns the next token as adouble.
Core Code Examples & Terminology
File: A Java class from thejava.iopackage whose objects represent the path to a file or directory on the disk.Scanner: A Java class from thejava.utilpackage that allows for parsing primitive types and strings from a stream of input, such as the console or a file.FileNotFoundException: A checked exception that occurs when a program attempts to open a file that cannot be found at the specified path.Checked Exception: A type of error that the Java compiler requires the programmer to acknowledge and handle, typically with a
throwsclause or atry-catchblock.Core Snippet 1 (File Reading Setup):
public void readFileData() throws FileNotFoundException { File dataFile = new File("input.txt"); Scanner fileScanner = new Scanner(dataFile); // ... loop to read data ... }This code properly instantiates
FileandScannerobjects and includes the requiredthrowsclause for handling a potentialFileNotFoundException.Core Snippet 2 (Reading by Line):
while (fileScanner.hasNextLine()) { String currentLine = fileScanner.nextLine(); System.out.println(currentLine); }This is the standard loop for processing a text file one full line at a time.
Core Snippet 3 (Reading by Token):
int count = 0; while (fileScanner.hasNext()) { String word = fileScanner.next(); count++; }This is the standard loop for processing a text file one token (e.g., word) at a time.
Core Skill Check
Code Tracing: A file
data.txtcontains10 20 thirty 40. What is the final value ofsumafter this Java code runs:int sum = 0; Scanner s = new Scanner(new File("data.txt")); while(s.hasNextInt()) { sum += s.nextInt(); }?- Answer:
30(The loop stops when it encounters "thirty").
- Answer:
Debugging: Identify the compile-time error in this Java code:
public void setupReader() { File f = new File("log.txt"); Scanner reader = new Scanner(f); }.- Error: The method signature is missing the
throws FileNotFoundExceptionclause.
- Error: The method signature is missing the
Application: Write a single line of Java code that reads the next available integer from a
Scannerobject namedfileInand stores it in anintvariable namedscore.- Answer:
int score = fileIn.nextInt();
- Answer:
Common Misconceptions & Errors
Forgetting
throws FileNotFoundException: This is the most common compile-time error. The compiler will not let you create aScannerfrom aFilewithout it.FileNotFoundExceptionat Runtime: This error occurs if the file does not exist in the location the program expects. File paths are typically relative to the project's root directory or execution folder.InputMismatchException: This runtime error occurs if you try to read a specific data type but the next token in the file does not match. For example, callingnextInt()when the next token is "hello".Infinite Loops: If your loop condition is
while(true)or you forget to call anext...()method inside awhile(hasNext...())loop, the scanner's position will never advance, and the loop will run forever.
Summary
Using text files allows Java programs to work with persistent data, making them more robust and scalable. The process relies on two key classes: File to represent the file's location and Scanner to parse its contents. The standard approach involves creating a Scanner from a File object and using a while loop with a hasNext...() condition to iterate through the data. Because opening a file can fail if it doesn't exist, methods that perform this action must declare that they throw a FileNotFoundException. By mastering this pattern, you can write programs that read, process, and analyze data from any plain text source.