FILE HANDLING

CONTENTS

1. Introduction
2. File Input
3. File Output
4. The File class


1. INTRODUCTION

When inputting and outputting to the screen we make use of the System.in and System.out objects as shown in Table 1 (the example is taken from the COMP101 lecture on keyboard input). System.in and System.out are special stream objects which read data from the keyboard and write data to the screen.

// HELLO WORLD PROGRAM 2
// Frans Coenen, Monday 15 January 1999
// Department of Computer Science, The University of Liverpool, UK

import java.io.*; 

class HelloWorld2 {
    // Create BufferedReader class instance

    static InputStreamReader input         = new InputStreamReader(System.in);
    static BufferedReader    keyboardInput = new BufferedReader(input);

    /* Main method  */

    public static void main(String[] args) throws IOException {
        String name;

        System.out.print("What is your name? ");
        name = keyboardInput.readLine();

        System.out.print("\nHello " + name );
        System.out.println(" - Congratulations on writing your first" +
                " Java program which features some input!\n\n");
        }
    }      

Table 1: Standard input/output

If we wish to read and write to a file we need to replace the in and out objects with appropriate alternative stream objects.



2. FILE INPUT

Before we can read from or write to a file we must first open the file. To open a file for reading we use the constructor contained FileReader class:

FileReader file = new FileReader("HelloWorld2.java");

This creates a stream object, called file, to read from a file called HelloWorld2.java (Table 1) contained in the current directory. If the named file cannot be opened a FileNotFoundException is generated. Consequently, whereas previously we declared instances of the InputStreamReader class as class instances we must now declare them as local instances within a method. Having done this we can now use the file object to create an instance of the BufferedReader class as before:

FileReader file          = new FileReader("HelloWorld2.java");
BufferedReader fileInput = new BufferedReader(file);

Note the similarity between this and the declarations used in the code given in Table 2:

 
InputStreamReader input         = new InputStreamReader(System.in);
BufferedReader    keyboardInput = new BufferedReader(input);

The BufferedReader constructor requires its argument to be an instance of the class Reader (or a sub-class of the class Reader), both the InputStreamReader and the FileReader classes are sub-callses of Reader and will therefore suffice. A class diagram illustrating the connections between these different classes is presented in Figure 1.

CLASS DIAGRAM SHOWING INPUT CLASS

Figure 1: Class diagram showing the connection between the different "reader" input classes.

Once we have finished reading from a file we should close it; this is achieved using the close instance method contained in the BufferedReader class. Because this is an instance method we must, of course, link it to an instance of the class BufferedReader:

fileInput.close();

The code presented in Table 2 reads the contents of the file HelloWorld2.java (presented in Table 1) and outputs the contents to the screen. Note that, in the Table 2, we keep reading from the file until we have read 31 lines. This is because we happen to know that the file in question is 31 lines long; this is not a very desirable mechanism, but will do for the moment to illustrate the principle of file input.

// FILE IO EXAMPLE 1
// Frans Coenen, Tuesday 4 January 2000
// Department of Computer Science, The University of Liverpool, UK

import java.io.*;

class FileIOExample1 {
    /* Main method  */

    public static void main(String[] args) throws IOException {
	FileReader file = new FileReader("HelloWorld2.java");
	BufferedReader fileInput = new BufferedReader(file);
    	String text;
	final int NUMBER_OF_LINES_IN_FILE = 31;
	
	// Read file and output
	
	for(int counter=0;counter < NUMBER_OF_LINES_IN_FILE;counter++) {
		text = fileInput.readLine();
		System.out.println(text);
		}
		
	// Close file
	
	fileInput.close();
        }
    }

Table 2: File input example



3. FILE OUTPUT

We have seen how we output to the screen (Table 1) using the system.out screen output object which is contained within the class System. An alteranative more generic approach can also be used where we create an instance of the PrintWriter "stream" class using the system.out object as shown in Table 3. Here we create an instance of the class PrintWriter, called screenOutput, which can be used in conjunction with the the print and printlnmethods contained in the printWriter class (as oposed to those methods with the same name contained in the PrintStream class and used in the example code in Table 1). The inter-relationship between the various output classes is illustrated by the class diagram presented in Figure 2.

CLASS DIAGRAM SHOWING OUTPUT CLASS

Figure 1: Class diagram showing the connection between the different output classes.

// HALO WORLD PROGRAM 4
// Frans Coenen
// Monday 15 January 1999
// The University of Liverpool, UK

// Import packages containing predefined classes

import java.io.*;

class HelloWorld4 {

    // ------------------- FIELDS ------------------------               
        
    // Create BufferedReader class instance

    public static InputStreamReader input         = 
    		new InputStreamReader(System.in);
    public static BufferedReader    keyboardInput = 
    		new BufferedReader(input);

    // Crerste PrintWriter class instance

    static PrintWriter screenOutput = new PrintWriter(System.out,true);

    // ------------------ METHODS ------------------------
    
    /* Main method  */
    
    public static void main(String[] args) throws IOException {
    	String name;
	
	screenOutput.print("What is your name? ");
	screenOutput.flush(); 
	name = keyboardInput.readLine();
	
	screenOutput.print("\nHello " + name );
	screenOutput.println(" - Congratulations on writing a more" + 
		" sophisticated Java program that inovles output!\n\n");
        }
    }

Table 3: Standard input/output

We can use esxactly the same approach to output to a file by replacing the System.out object with an alternative "output to file" object. The Java class FileWriter class contained in the java.io package includes a constructor (with a single argument that must be a string) that creates such an object. The argument is the name of the file which we wish to write to (if there is no such file then Java will create one). Thus if we wish to (say) write to a file called myFile then we would have to create an instance of the class FileWriter (lets call it file) as follows:

FileWriter file = new FileWriter("myFile");

We now have an "output to file" object called file which we can use to create a PrintWriter object:

PrintWriter fileOutput = new PrintWriter(file);

which can be used as follows:

fileOutput.print("Halo World")

or:

fileOutput.println("Halo World Again")

Thus to write to a file we replace the System.out stream object with an appropriate "file output" stream object. We create such an object using the FileWriter class constructor as shown above. However, the class FileWriter does not contain the instance methods print and println which we would like to use. These are contained in the PrintWriter class, thus we must also create an instance of this class.

We can now adapt the code given in Table 2 so that the contents of the file HelloWorld2 are output to a file called testFile; this is done in Table 4.

// FILE IO EXAMPLE 2
// Frans Coenen, Tuesday 4 January 2000
// Department of Computer Science, The University of Liverpool, UK

import java.io.*;

class FileIOExample2 {

    /* Main method  */

    public static void main(String[] args) throws IOException {
	FileReader file1 = new FileReader("HelloWorld2.java");
	BufferedReader fileInput = new BufferedReader(file1);
	FileWriter file2 = new FileWriter("testFile");
	PrintWriter fileOutput = new PrintWriter(file2);
    	String text;
	final int NUMBER_OF_LINES_IN_FILE = 42;
	
	// Read file and output
	
	for(int counter=0;counter < NUMBER_OF_LINES_IN_FILE;counter++) {
		text = fileInput.readLine();
		System.out.println(text);
		fileOutput.println(text);
		}
		
	// Close file
	
	fileInput.close();
	fileOutput.close();
        }
    }

Table 4: File input and output example



4. THE File CLASS

We express the location of a file using a path name (absolute or relative). The File class contains (amongst other things) a number of methods that can be used to check whether a named file exists or not. In Table 5, the code presented in Table 2 is repeated but with the inclussion of a method to check a file name, this time presented as a command line argument, using some of the methods contained in the File class.

// FILE IO EXAMPLE 3
// Frans Coenen, Wednesday 24 January 2001
// Department of Computer Science, The University of Liverpool, UK

import java.io.*;

class FileIOExample3 {

    /* Main method  */

    public static void main(String[] args) throws IOException {
	String fileName = new String(args[0]);
	
	// CheckFile
	
	if (!checkFile(fileName)) System.exit(1);
	
	// Process
	
	FileReader file = new FileReader(fileName);
	BufferedReader fileInput = new BufferedReader(file);
    	String text;
	final int NUMBER_OF_LINES_IN_FILE = 31;
	
	// Read file and output
	
	for(int counter=0;counter < NUMBER_OF_LINES_IN_FILE;counter++) {
		text = fileInput.readLine();
		System.out.println(text);
		}
		
	// Close file
	
	fileInput.close();
        }

    /* Check File */
    	
    private static boolean checkFile(String fileName) {
        File src = new File(fileName);
    
    	if (src.exists()) {
            if (src.canRead()) {
	    	if (src.isFile()) return(true);
	    	else System.out.println("ERROR 3: File is a directory");
	    	}
	    else System.out.println("ERROR 2: Access denied");
	    }
    	else System.out.println("ERROR 1: No such file");
    
    	return(false);
    	}
    }

Table 5: File input example with "file check"




Created and maintained by Frans Coenen. Last updated 21 May 2003