This chapter’s examples have provided explicit details for several ways of writing data to files and reading data from files. In actual programs, deciding if and how files might be useful in the program are worked out as part of the design process. Choosing between text files, binary files, and reading and writing objects is part of this process.
To illustrate how we can apply what we’ve learned about file I/O, let’s modify the WordGuess class (Listing 9.11.5) so that it reads a list of possible words for players to guess from a file. The Chapter 8 version of the class contains a method, getSecretWord(), which uses a switch statement to randomly choose and return a word from a fixed list of ten words. Reading the words from a text file would allow a user to modify the list of possible words by adding or changing words without needing to recompile the program.
Let’s modify the WordGuess class in three ways:
adding two new instance variables, an array of type String and a variable to store the size of the array;
adding code at the beginning of the class’s constructor to read words from the file and store them in the array;
rewrite the getSecretWord() method so that it randomly chooses a word from the array.
Let us first choose descriptive names for declaring the two new instance variables:
private String[] wordArray;
private int arraySize;
Note that it will be useful to store the number of words in the file in its first line so that this information can be used to allocate memory for the array. For example, let us assume the text file will be named secretwords.txt, it will be located in the same directory as the WordGuess class, it will have the number of words in the file as its first line, and it will have a single word per line after that. Thus, a small file might look like:
3
STREAMS
CONDUIT
DIALOGS
We can use the body of the readTextFile() method of the TextIO class as a model for the Java code that needs to be added to the WordGuess constructor. Pseudocode for this code will look like:
Algorithm11.7.1.Read textfile algorithm.
Use file name to open a BufferedReader stream
Read first line and convert to an integer
Store the integer as the size of the array
Allocate memory for the array
Read second line of file
While a word is read
Store the word in the next array element
Read next line of file
Close the BufferedReader stream
When this pseudocode is translated into Java and inserted into a try-catch statement we get the code fragment in Listing 11.7.2.
The new getSecretWord() method merely needs to generate a random array index and return the corresponding array element:
private String getSecretWord() {
int num = (int)(Math.random()*arraySize);
return wordArray[num];
} //getSecretWord()
The only other modification that is needed for to complete new WordGuess class is to add an initial import java.io.*; statement so that the file IO classes can be accessed.
The earlier examples in this chapter can be used as models to enhance numerous practical applications. GUI applications that involve a user’s choice to load data from a file or save data in a file should make use of the JFileChooser dialogs to initiate the file operations.