Reading from a file

The Scanner class is useful not just for reading input that the user types into the output pane, but can also be used to read text data from a file. To set up a Scanner to read from the output pane, we use the syntax

Scanner input = new Scanner(System.in);

To set up a Scanner to read from a text file, we instead use the syntax

Scanner input = new Scanner(new File("numbers.txt"));

where numbers.txt is the name of the text file we want to read from.

One small complication you are going to encounter when you try to use the code above to create a Scanner to read from a file is that the Scanner needs a File object to tell it where the file it should read from is. Unfortunately, creating a File object may generate an exception: if the file we have named does not exist, Java may throw a FileNotFound exception. NetBeans will note this possibility and force you to include some extra code that potentially intercept that exception and handle it should it occur. The code below will take care of that:

Scanner input = null;
try {
    input = new Scanner(new File("numbers.txt"));
} catch (Exception ex) {
    ex.printStackTrace();
}

Should we attempt to open a file that does not exist, the command new File("numbers.txt") will generate an exception, which will cause us to enter the catch block. In the catch block we can tell the exception object to print some additional details about what went wrong to the output pane.

In addition to the exception handling code, you will also need to place an import statement at the top of your program to import the File class:

import java.io.File;

Creating a text file to read from

To make a text file in NetBeans, start by right-clicking on the project in the project pane. (The project is the thing with the coffee cup icon next to it.) From the context menu, select the option New/Other...

In the dialog box that appears, select the category Other at the bottom of the list of file type categories, and then select 'Empty File' from the list of file types on the right. Click Next to move to the second part of the New File dialog.

In this dialog you will type the name of the file. Clicking Finish creates and opens the text file for you to start typing data into it.

If you need to locate the text file at some later point, you will be able to access it in the Files pane in NetBeans.

First example program - reading numbers from a text file

Here is the code for a first simple example program that demonstrates how to read a list of integers from a text file:

package fileexamples;

import java.io.File;
import java.util.Scanner;

public class ReadNumbers {

    public static void main(String[] args) {
        Scanner input = null;
        try {
            input = new Scanner(new File("numbers.txt"));
        } catch (Exception ex) {
            System.out.println("Can not open file.");
            System.exit(0);
        }
        while(input.hasNextInt()) {
            int number = input.nextInt();
            System.out.println(number);
        }
        input.close();
    }
}

This program opens a Scanner to read from the text file named "numbers.txt". If the input file is not present, the program will print a message and then exit, otherwise we go on to read data from the file. Once the Scanner is open on the file, we can use the usual command nextInt() to read the next available integer from the file. The program will attempt to read all of the numbers in the text file and print them to the output pane.

One complication with input from files is that we may not know in advance how many numbers are in the text file. To help with this, the Scanner class offers a useful method hasNextInt() that returns true if there are more numbers available to be read from the file and false once we have read to the end of the file. As you can see in the example program, we can use hasNextInt() to control a while loop that reads numbers from the file until all of the numbers have been read.

A search problem

Here is a typical example of a search problem: given a list of numbers in a file that appear in no particular order, find the smallest and largest numbers in the file.

To solve this problem we set up two variables, one to store the smallest number we have seen so far, and one to store the largest number we have seen so far. We start by reading the first number from that file: that number is simultaneously both the smallest and largest number we have seen so far. Then, as we read through the rest of the numbers in the file we compare each new number against these variables to see whether we have found a new largest or smallest number.

public static void main(String[] args) {
    Scanner input = null;
    try {
        input = new Scanner(new File("numbers.txt"));
    } catch (Exception ex) {
        System.out.println("Can not open file.");
        System.exit(0);
    }

    int smallest = input.nextInt();
    int largest = smallest;

    while(input.hasNextInt()) {
        int number = input.nextInt();
        if(number < smallest)
            smallest = number;
        if(number > largest)
            largest = number;
    }
    input.close();

    System.out.println("The numbers in the file fall in the range from " + smallest + " to " + largest);
}

Writing to a file

Sometimes we will find ourselves writing programs that generate a lot of output. If we would like to save that output to use later, we can arrange for the program to print its output to a file instead of to the output pane in NetBeans.

The next example shows how to do this. For this example I took one of the examples from the lecture on loops and rewrote it to write its output to a file instead of to System.out. The example is a program that generates a list of all of the prime numbers from 1 to 1000.

public static void main(String[] args) {
    PrintWriter pw = null;
    try {
        pw = new PrintWriter(new File("primes.txt"));
    } catch (Exception ex) {
        System.out.println("Can not open file for writing.");
        System.exit(0);
    }

    int n = 3;
    while (n < 1000) {
        int d = n - 1;
        while (d > 1) {
            if (n % d == 0) {
                break;
            }
            d--;
        }

        if (d == 1) {
            pw.println(n);
        }

        n = n + 2;
    }
    pw.close();
}

Here are some things to note about this example.