Section 4.6. From the Java Library: java.io.File and File Input (Optional)


[Page 183 (continued)]

4.6. From the Java Library: java.io.File and File Input (Optional)

In addition to command-line and GUI user interfaces, there is one more standard user interface, files. In this section we show how the Scanner class, used in Chapter 2 for keyboard input, can also read input from files. Reading input from a file is relevant to only certain types of programming problems. It is hard to imagine how a file would be used in playing the One-Row Nim game, but a file might very well be useful to store a collection of riddles that could be read and displayed by a Java program. We will develop such a program later in this section.

java.sun.com/docs


Java has two types of files, text files and binary files. A text file stores a sequence of characters and is the type of file created by standard text editors like NotePad and WordPad on a Windows computer or SimpleText on a Macintosh. A binary file has a more general format that can store numbers and other data the way they are stored in the computer. In this section we will only consider text files. Binary files are considered in Chapter 11.

4.6.1. File Input with the File and Scanner Classes

An instance of the java.io.File class stores information that a Scanner object needs to create an input stream 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 only need to use the File() constructor in this section. The File instance created with the statement

File theFile = new File("riddles.txt"); 


Figure 4.26. A UML class diagram of the File class with a partial list of public methods.


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 namethat 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.


[Page 184]

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 that there is a Scanner() constructor with a File object as an argument. Unlike the create() method 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:

try {   File theFile = new File("riddles.txt");     fileScan = new Scanner(theFile);     fileScan = fileScan.useDelimiter("\r\n"); } catch (IOException e) {    e.printStackTrace(); } // catch() 


Figure 4.27. A UML class diagram of the Scanner class with an expanded list of public methods.


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 is 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 is more data in the file.

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

String ques = null; String ans = null; Riddle theRiddle = null; 


Figure 4.28. A program that reads riddles from a file and displays them.
(This item is displayed on page 185 in the print version)

import java.io.*; import java.util.Scanner; public class RiddleFileReader {  private Scanner fileScan; // For file input    private Scanner kbScan;   // For keyboard input    public RiddleFileReader(String fName)    {   kbScan = new Scanner(System.in);        try        {   File theFile = new File(fName);            fileScan = new Scanner(theFile);            fileScan = fileScan.useDelimiter("\r\n");        } catch (IOException e)        {    e.printStackTrace();        } // catch()    } // RiddleFileReader() constructor    public Riddle readRiddle()    {   String ques = null;        String ans = null;        Riddle theRiddle = null;        if (fileScan.hasNext())            ques = fileScan.next();        if (fileScan.hasNext())        {   ans =  fileScan.next();            theRiddle = new Riddle(ques, ans);        } // if        return theRiddle;    } // readRiddle()    public void displayRiddle(Riddle aRiddle)    {   System.out.println(aRiddle.getQuestion());        System.out.print("Input any letter to see answer:");        String str = kbScan .next();  // Ignore KB input        System.out.println(aRiddle.getAnswer());        System.out.println();    } // displayRiddle()    public static void main(String[] args)    {   RiddleFileReader rfr =            new RiddleFileReader("riddles.txt");        Riddle riddle = rfr.readRiddle();        while (riddle != null)        {   rfr.displayRiddle(riddle);            riddle = rfr.readRiddle();        } // while    } // main() }  // RiddleFileReader class 


[Page 185]

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

if (fileScan.hasNext())     ques = fileScan.next(); if (fileScan.hasNext()) {   ans = fileScan.next();     theRiddle = new Riddle(ques, ans); } 



[Page 186]

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. The following three riddles saved in a text file would comprise a good example to test the RiddleFileReader class.

What is black and white and red all over ? An embarrassed zebra What is black and white and read all over ? A newspaper What other word can be made with the letters of ALGORITHM ? LOGARITHM 


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

What is black and white and red all over ? Input any letter to see answer: X An embarrassed zebra What is black and white and read all over ? Input any letter to see answer: 


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 there.

Self-Study Exercise

Exercise 4.3

Modify the RiddleFileReader class to create a program NumberFileReader that 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.




Java, Java, Java(c) Object-Orienting Problem Solving
Java, Java, Java, Object-Oriented Problem Solving (3rd Edition)
ISBN: 0131474340
EAN: 2147483647
Year: 2005
Pages: 275

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net