sepbar-1.gif (3106 bytes)

Java 103 : File-handling under Java

Written by David Reilly, March 1, 1997 sepbar-1.gif (3106 bytes)
Previous | Next


Editor's Note :  With the introduction of JDK1.1, there is now a second way to read and write to files. This tutorial discusses streams, but JDK1.1 also supports readers and writers. Readers and writers are generally used only for text data, whereas InputStream and OutputStream is used for binary data.

-- David Reilly, May 1999


One of the first things a programmer learns with a new language is how to read and write to files, since the saving and loading of data will be an important feature of most software he or she will eventually develop using that language.

Java offers extensive - yet easy to use - file handling classes that make it a breeze to read and write files. In this tutorial, we'll start by covering the basics of file input and output, as well as covering some associated topics, such as trapping exceptions and I/O errors. I'll present two Java examples - one covering file output, and one covering file input.

File output

Our first example will be a program that writes a string to a file. In order to use the Java file classes, we must import the Java input/output package (java.io) in the following manner

Inside the main method of our program, we must declare a FileOutputStream object. For those familiar with C, a FileOutputStream is analogous to a file handle. When we send a stream (or sequence) of data to the FileOutputStream handle, data will be written to disk.

In Java, there exists a large number of extensions to the standard input and output stream classes. This is handy, as the basic input and output streams deal only with the transfer of bytes - not the easiest way for us to write out data. There's a wide variety of streams to choose from : if we were writing data such as bytes, integers, floats, or other "data" orientated types, we might choose the DataOutputStream, whereas for text we'd use the PrintStream class.

In this case, we wish to write a string to the file, and so we create a new PrintStream object that takes as its constructor the existing FileOutputStream. Any data we send from PrintStream will now be passed to the FileOutputStream, and ultimately to disk. We then make a call to the println method, passing it a string, and then close the connection.



/*
 *
 * FileOutputDemo
 *
 * Demonstration of FileOutputStream and
 * PrintStream classes
 *
 */

import java.io.*;

class FileOutputDemo 
{	

        public static void main(String args[])
        {              
                FileOutputStream out; // declare a file output object
                PrintStream p; // declare a print stream object

                try
                {
                        // Create a new file output stream
                        // connected to "myfile.txt"
                        out = new FileOutputStream("myfile.txt");

                        // Connect print stream to the output stream
                        p = new PrintStream( out );
		
                        p.println ("This is written to a file");

                        p.close();
                }
                catch (Exception e)
                {
                        System.err.println ("Error writing to file");
                }
        }
}

Listing 1.0 - FileOutputDemo.java


After running the output example, and seeing that it wrote to our file, let's take a more detailed look at the code. You may be wondering what the purpose of the try { .. } catch block is. Rather than checking for erroneous return values (such as a null pointer when obtaining an output stream as is the case with C's fopen), we catch exceptions.

Exceptions are events that occur in exceptional or unusual circumstances, such as error conditions. A method can throw an exception, to indicate to the calling object that a non-standard circumstance has occurred. Thus, instead of checking each and every file method call, we have one piece of code handling all possible errors!

File input

File input under Java differs little from file output. We must import the Java IO package, and we create a file input stream inside of a try { .. } catch block as in the previous example.

In this example, the file we open is given to us as the first command line parameter. We obtain this by examining the args array of strings. Since an array is an actual object in Java, we can find the length of the array (and hence the number of parameters) through the length attribute.

To do anything useful with file input, we create a DataInputStream which can handle reading in data as well as lines of text. To determine if there is any data left to read, we call the available() method of our input stream. This method returns the number of bytes remaining, which we check to see is not equal to zero. Then we call the DataInputStream's readLine() method and print the result to the screen.



/*
 *
 * FileInputDemo
 * Demonstrates FileInputStream and
 * DataInputStream
 */
import java.io.*;

class FileInputDemo 
{
        public static void main(String args[])
	{
                // args.length is equivalent to argc in C
                if (args.length == 1)
		{
                        try
			{
                                // Open the file that is the first 
                                // command line parameter
                                FileInputStream fstream = new 
					FileInputStream(args[0]);

                                // Convert our input stream to a
                                // DataInputStream
				DataInputStream in = 
                                        new DataInputStream(fstream);

                                // Continue to read lines while 
                                // there are still some left to read
                                while (in.available() !=0)
				{
                                        // Print file line to screen
					System.out.println (in.readLine());
				}

				in.close();
			} 
                        catch (Exception e)
			{
				System.err.println("File input error");
			}
		}
                else
                                System.out.println("Invalid parameters");
	}

}

Listing 1.1 - FileInputDemo.java


After executing the program, and providing a valid filename, you'll see how easy it is to read and process files. There are a wide variety of methods supported by the DataInputStream class, which make it easy to read in almost any data type. For further information, consult your Java API.

In the next installment of this tutorial series, we'll be covering some of the more advanced object-orientated features of Java - in particular the way in which classes can be extended through inheritance. 

Previous | Next

<-- Back to the Java Coffee Break