Lab 4_2 Files, File Choosers, and Scanners

You probably worked with files in your previous course: but here is a quick refresher. There are two ways to identify a file in Java.

  1. The name of a file
  2. Using the File object. This is a type of object that describes a file as it is stored on the computer's file system. The file system is the system of directories (folders) that the operating system uses to organize stored files so users can find them easily.

You can find out more about File online, just type java 6 File into your favourite search engine. Here we just need to know that when you use a file chooser (which we will discuss next) to locate a file in the file system, the file chooser gives you access to the file selected by the user through a File object. You can see an example of a Java file chooser dialog in action below.

Here the user has used the JFileChooser dialog box to navigate to the Documents folder and select a file named infix.txt.

To use a JFileChooser, you need to know about the following constructor and methods:

JFileChooser()
int showOpenDialog(Component owner)
File getSelectedFile()

Using a JFileChooser

Look up the JFileChooser documentation online so you know what package to import. To use it, create a JFileChooser object and then call its showOpenDialog(). If you have a GUI application, pass it the Component you want it to appear on top of. This will generally be the JFrame for your application. If you are using a console application, just pass it null. Calling this method will cause a dialog box like the one below to appear:

The user will use the dialog to navigate to some folder and select a file, and then click on the Open button to accept the selected file. If the user changes his (or her) mind, he or she can click on Cancel. Either, way, the showOpenDialog will return an integer to your program indicating the user's choice. If the the user selected a file, the method will return the value JFileChooser.APPROVE_OPTION. At this point, you can call the getSelectedFile() to retrieve a File object that you can use to access the file.

Here is example code for using a file chooser object.

       File file = null;
       JFileChooser chooser = new JFileChooser();
       int result = chooser.showOpenDialog(null);       
       if (result == JFileChooser.APPROVE_OPTION)
         file = chooser.getSelectedFile();
       else
       {
           JOptionPane.showMessageDialog(null, "No file selected");
           System.exit(1);
       }

If this code does not exit, you will have a File object named file. Next, let us look at how you can use this object to open and read a text file using a Stream object named a FileReader.

FileReader

A FileReader object is used to read text files. Text files are files that are human-readable, usually created by a text editor such as Notepad. Many applications, for example MS Word, Excel, and Access, do not create text files. Instead, they create a different type of file named a binary file. You cannot use a FileReader to read a binary file.

If you look up the documentation for the FileReader class, you will see that it has two constructors

FileReader(File file)  throws FileNotFoundException
FileReader(String fileName) throws FileNotFoundException

You use these constructors to create a FileReader object to read a file identified either by its string name or by a File object previously obtained from the getSelectedFile() of a JFileChooser (you can also obtain File objects from other sources. The constructor will automatically open the file so you can read it. If something goes wrong, the constructor throws the FileNotFoundException. This is a special case (subclass) of another type of excepton called IOException, which is the type of exception thrown whenever something goes wrong with an IO operation.

Look up the FileReader documentation to find out what package to import when you use FileReader.

Methods to use on FileReader

If you look in the documentation for FileReader, you will not find any methods. This is because it only uses methods inherited from its superclass, a type of Stream class called InputStreamReader. Here are a couple of InputStreamReader methods.

 int read()  throws IOException
 void close() throws IOException
 

The read() method, when called, returns an integer from representing the Unicode of the next character available from the file, and returns -1 when there are no more characters to return. To read a file, you use a loop that keeps calling read() until read() returns -1. At that point you know you are at the end of file. You must cast the integer returned by read() to a char to treat it as a character. When you are done using the stream, close the stream using close(). Here is an example of reading a file and copying its contents to the screen.

 
 public class Main
{
    public static void main(String[] args) throws IOException
    {
       // Use file dialog to select file.
       JFileChooser chooser = new JFileChooser();
       int result = chooser.showOpenDialog(null);
       // This assumes user pressed Open
       // Get the file from the file 
       File file = chooser.getSelectedFile();
       // Open the file
       FileReader reader = new FileReader(file);

       // Use read, which returns an int
       int i = reader.read();
       while (i != -1)
       {
           // Convert to char and print
           char ch = (char)i;
           System.out.print(ch);
           // Get next  from read()
           i = reader.read();
       }
       // reader.close();
     }
}

Notice that you have to add a

throws IOException

to the header for the main method.

1. Test Your Understanding

Write a program that opens a text file and copies it to the screen, with all characters transformed to upper case.

2. Test Your Understanding

Write a program that opens a text file, copies its contents to the screen, and then prints the length of the file (that is, it prints the number of characters in the file).

Scanners on File objects

The FileReader is great for reading a file one character at a time. If you want to identify words in the file (assuming that words are delimited by white space), or you need to read integers or doubles from the file, you need to put a Scanner object on top of a file. Assuming file is an object of type File, you do that like this

Scanner sc = new Scanner(file);

Once you have the scanner on the file, you can use the scanner methods

boolean hasNext()
String next()
boolean hasNextLine()
String nextLine()
boolean hasNextInt()
int nextInt()

Look up the documentation for these Scanner class methods. Make sure you understand what they do. If you do not, ask the preceptor, or the professor.

3. Test Your Understanding

Write a program that opens a text file and copies its contents to the screen in double space format. This means that you will insert a blank line after every line you read from the file.

4. Test Your Understanding

Write a program that counts the number of lines in a file and prints this number out.

5. Test Your Understanding

Write a program that counts the number of words in a file and prints this number out.

6. Test Your Understanding

Write a program that determines and prints both the number of words and the number of lines in the file. Hint: You can put a Scanner object on a String object!

7. Test Your Understanding

Assume that you have a text file that contains positive integers separated by white space. There is at least one integer, but you do not know how many integers are in the file. Write a program that opens the file and prints the sum of all integers in the file. For example, the contents of the file might look like this:

12 7 8
2  5

In this case your program would print 34.

You do not have to hand in this lab, but this material will be on the test next week.