Resources‎ > ‎Java Basics‎ > ‎

File IO

The java.io package provides input and output streams that enable the programmer to read data from and write data to various sources. Unsurprisingly, the FileReader class allows the programmer to read character data from a file. The Scanner is significantly more useful for processing text as it enables you to read data a line at a time from a file.  Similarly, the FileWriter class allows you to write data to a file a character at a time, while the PrintWriter supports the println operation, the same method you call when you output text to the standard output (e.g., System.out.println("Hello")),

Take a look at the example below and notice the following:

Importing the java.io Package

In order to use the classes provided in the java.io package, you must import them. Recall that using "*" (e.g., import java.io.*;) will import all of the classes in a particular package.

Wrapping Streams

Creating input and output streams requires several steps. In order to create a PrintWriter you must first create a FileWriter, the constructor of which takes as input a file name.

Exceptions

Most of the code in the example below is enclosed in a try/catch statement. Instantiating new Reader objects, as well as invoking methods to read and write data, all may result in an exceptional situation. For example, the file you attempt to open may not be found, or the file you attempt to read from may be empty. In these cases, an exception is thrown. 

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;


public class FileIO {

    /**
     * @param args
     */
    public static void main(String[] args) {

        Scanner scan = null;
        PrintWriter writer = null;

        try {
            scan = new Scanner(new FileReader("file.txt"));
            writer = new PrintWriter(new FileWriter("output.txt"));


            while(scan.hasNext()) {
                String line = scan.nextLine();
                writer.println(line);
            }
           
        } catch(IOException ioe) {
            System.out.println("FileIO.main::Error reading/writing file");
            ioe.printStackTrace();
        } finally {
            scan.close();
            writer.close();
        }
    }

}

Closing the File/Finally

The example above illustrates the use of the finally clause. The finally clause always executes, regardless of whether an exception is thrown. If no exception is thrown, all of the try part will execute, followed by the finally clause. If an exception is thrown, the try part will execute until the exception is thrown, the catch part will execute, and then the finally part will execute. The finally is quite commonly used to clean up after file IO. In this case, it ensure that the files are closed whether an exception was thrown or not.

Relative and Absolute Paths

The example above uses relative paths. In this case, the program will look in the directory where the program is located to find the files. Similarly, if we replaced "file.txt" with "text_files/file.txt", the program would look in the test_files directory of the current directory and attempt to locate the file file.txt.

Alternatively, we could use absolute path names. On a unix system, that would look something like this: "/home/srollins/cs112/file.txt”. On a windows system, it would look something like this: “C:\\srollins\\cs112\\file.txt”

Random tip: Never use spaces in your file or directory names.

Comments