and File Input

Section 4.6 describes and illustrates how to get the values of method arguments from a file.

2. File Input with the File and Scanner Classes

An instance of the class stores information that a Scanner object needs to create an input stream that is connected to the sequence of characters in a text file. A partial list of the public methods of the File class is given in the UML class diagram in Figure 4.26. We will need to use only the File() constructor in this section. The File instance created with the statement

Annotation 2020-03-29 153505

will obtain and store information about the ”riddles.txt” file in the same directory as the java code being executed, if such a file exists. If no such file exists, the File object stores information needed to create such a file but does not create it. In Chapter 11, we will describe how other objects can use a file object to create a file in which to write data. If we wish to create a File object that describes a file in a directory other than the one containing the Java program, we must call the constructor with a string argument that specifies the file’s complete path name—that is, one that lists the sequence of directories containing the file. In any case, while we will not use it at this time, the exists() method of a File instance can be used to determine whether or not a file has been found with the specified name.

In order to read data from a file with a Scanner object we will need to use methods that were not discussed in Chapter 2. An expanded list of methods of the Scanner class is given in Figure 4.27. Note the there is a Scanner() constructor with a File object as an argument. Unlike the other create() method that was used in Chapter 2, this create() throws an exception that must be handled. The following code will create a Scanner object that will be connected to an input stream that can read from a file:

Annotation 2020-03-29 153657

We will discuss the try-catch commands when exceptions are covered in Chapter 10. Until then, the try-catch structures can be copied exactly as above, if you wish to use a Scanner object for file input. In the code above, the useDelimiter() method has been used to set the Scanner object so that spaces can occur in strings that are read by the Scanner object. For the definition of a class to read riddles from a file, the above code belongs in a constructor method.

After we create a Scanner object connected to a file, we can make a call to nextInt(), nextDouble(), or next() method to read, respectively, an integer, real number, or string from the file. Unlike the strategy for using a Scanner object to get keyboard input, it is suggested that you test to see if there is more data in a file before reading it. This can be done with the hasNext(), hasNextInt(), and hasNextDouble() methods. These methods return the value true if there are more data in the file.

The program in Figure 4.26 is the complete listing of a class that reads riddles from a file and displays them. Note that, in the body of the method readRiddles(), the statements:

Annotation 2020-03-29 154220

make explicit the fact that variables that refer to objects are assigned null as a value when they are declared. The statements:

Annotation 2020-03-29 154306

will read Strings into the variables ques and ans only if the file contains lines of data for them. Otherwise the readRiddle() method will return a null value. The main() method uses this fact to terminate a while loop when it runs out of string data to assign to Riddle questions and answers. There is a separate method, displayRiddle() using a separate instance of Scanner attached to the keyboard to display the question of a riddle before the answer.

The contents of the ”riddles.txt” file should be a list of riddles with each question and answer on a separate line. For example The following three riddles saved in a text file would form a good example to test the RiddleFileReader class.

Annotation 2020-03-29 154435

Annotation 2020-03-29 154018Annotation 2020-03-29 153933

When the main() method is executed, the user will see output in the console window that looks like:

Annotation 2020-03-29 154538

Files are covered in depth in Chapter 11. Information on writing data to a file and reading data from a file without using the Scanner class can be found in that chapter.


EXERCISE 4.3 Modify the RiddleFileReader class to create a program NumberFileReaderthat opens a file named ”numbers.txt” and reports the sum of the squares of the integers in the file. Assume that the file ”numbers.txt” contains a list of integers in which each integer is on a separate line. The program should print the sum of the squares in the System.out console window. In this case, there is no need to have a method to display the data being read or a Scanner object connected to the keyboard. You will want a constructor method and a method that reads the numbers and computes the sum of squares.