Next page | Contents page |

File input & output

There is a large and baffling set of classes in the standard API package java.io representing files for reading and writing their contents. Another package, java.nio (new I/O), more recently added to that. Some other packages also have classes for reading and writing files; an example is javax.imageio. The following are in java.io and I have grouped them according to functionality.

java.lang.Object
   |
   |_____RandomAccessFile
   |
   |
   |_____InputStream
   |           |
   |           |__ByteArrayInputStream
   |           |__FileInputStream
   |           |__FilterInputStream
   |  (byte    |      |
   |  streams) |      |__BufferedInputStream
   |           |      |__DataInputStream
   |           |      |__PushbackInputStream
   |           |
   |           |__ObjectInputStream
   |           |__PipedInputStream
   |           |__SequenceInputStream
   |
   |_____OutputStream
   |           |
   |           |__ByteArrayOutputStream
   |           |__FileOutputStream
   |           |__FilterOutputStream
   |           |      |
   |           |      |__BufferedOutputStream
   |           |      |__DataOutputStream
   |           |      |__PrintStream
   |           |
   |           |__ObjectOutputStream
   |           |__PipedOutputStream   
   |
   |______Reader
   |           |
   |           |__BufferedReader
   |           |__CharArrayReader
   |           |__FilterReader
   |(character |__InputStreamReader
   |  streams) |      |
   |           |      |__FileReader
   |           |
   |           |__PipedReader
   |           |__StringReader
   |
   |______Writer
               |
               |__BufferedWriter
               |__CharArrayWriter
               |__FilterWriter
               |__OutputStreamWriter
               |      |
               |      |__FileWriter
               |
               |__PipedWriter
               |__PrintWriter
               |__StringWriter

We are now going to look at just a few of those.

Systems generally have a console comprising a keyboard and a display. These are the default input and output devices and we use input and output streams to read from and write to them, respectively. We will look at those first before going on to read and write text files held on a storage device.

Console I/O

	// Assume import java.io.*;

	try
	{
	   BufferedReader keyboard = new BufferedReader (
				 new InputStreamReader (System.in));
	   System.out.println ("Who are you?");
	   String s = keyboard.readLine ();
	   System.out.println ("Hello " + s);
	}
	catch (IOException ex) 
	{
	   ex.printStackTrace (); 
	}

We had met java.lang.System.out before. It is an object of class java.io.PrintStream, a character stream going to the console display.

Corresponding to that, java.lang.System.in is a java.io.InputStream (byte stream) coming from the keyboard. Here we wrap it in an InputStreamReader (and then a BufferedReader) in order to read characters rather than bytes.

java.lang.System

Has useful static fields and methods. It cannot be instantiated (how can that be ensured?)

Fields err, in, out are the 3 standard system I/O streams. err & out are wrapped as java.io.PrintStreams.

The example above read a whole line from the keyboard, when the user pressed the Enter key. But individual keys can be read: int key = System.in.readch ();

Other useful methods in the class:

System.getProperty ("user.dir"); 	  // Current directory
long t = System.currentTimeMillis (); // Milliseconds since 1970.0
System.gc ();  		// Tell JVM to do garbage collection *
System.exit (status); 	// Exit program (security permitting)
System.arraycopy ()

* No longer recommended in web servers

Reading a text file

	// Assume import java.io.*;

	try
	{  
		BufferedReader in = null;

		try
		{  
			in = new BufferedReader (new FileReader (filename));
			String line;
			
			while (null != (line = in.readLine ()))
			// Note the combination of assignment and test - useful
			{
				System.out.println (line);
			}
		}
		finally
		{
			if (null != in)
			{
				in.close (); // Best practice: always release resources
			}
		}
	}
	catch (IOException ex)
	{
		ex.printStackTrace ();
	}

Notice the use of nested try blocks. The inner one ensures that the file is closed whatever the outcome. The outer one ensures that if a java.io.IOException occurs it will be reported. printStackTrace () is a method of all Exception objects that prints on the system console. We have already noted that logging to a file would be preferred in a real application.

It is expected that Java 7 will modify exception handling so that a single try block can be used here.

Notice also two things about the way have declared the BufferedReader: (a) so that it is available both in the inner try block and its finally clause; (b) setting it to null: when object variables are declared as class fields they are automatically set to null but when they are local variables, as here, they are not set to anything (this is a general rule, worth remembering) - the result is that the compiler complains about the test for it being null because there is a possible route through the code in which it has not been set, unless we explicitly set it to null in the declaration, as we have shown.

Writing a text file

	// Assume import java.io.*;

	try
	{
		PrintWriter out = null;
		
		try
		{
			out = new PrintWriter (new FileWriter (filepath));
			out.println ("A line of text\nAnother line");
			out.println ("A third line");
			out.print ("Start of final line ");
			out.print ("... and some more");
			out.println ();  // Just a line feed
		}
		finally
		{
			if (null != out)
			{
				out.close ();  // Essential: flushes data to disc
			}
		}
	}
	catch (IOException ex)
	{
		ex.printStackTrace ();
	}
Next page | Contents page |