Java I/O


The InputStream and OutputStream classes

Input and output in Java are handled through subclasses of the java.io.InputStream and java.io.OutputStream classes.  These classes are abstractions that Java provides for dealing with reading and writing information sequentially to/from anything you want, be it a disk, a string buffer, an enumeration, or an array of bytes.

For instance, if I want to read the contents of a text file into a String, I might use the following code:

    import java.io.*;
 

    ...
 

    String buffer = new String();

    // read bytes until eof
    try
    {
        // FileInputStream constructor takes either a String, a File object, or a FileDescriptor object
        FileInputStream infile = new FileInputStream("myfile.txt");

        for(int i = infile.read(); i != -1; i = infile.read())
        {
            buffer += (char) i;
        }

        infile.close();
    }
    catch(IOException e)
    {
        System.err.println("Could not read from myfile.txt");
    }
    catch(FileNotFoundException e)
    {
        System.err.println("myfile.txt not found");
    }
 

The InputStream's available() method returns the number of bytes that can be read from the stream, and the close() method closes the link between the program and the source of the data.  After you close the stream, you cannot read from it anymore until you open it up again.  The reset() method sends the "pointer" to the stream back to the top of the file.  Several read() methods exist that you can use.  All data comes out as ints or bytes--to convert to chars you will have to cast them.

Similar methods exist for OutputStream.


The System class

The java.lang.System class is a useful class containing useful static members doing useful things.  This should look familiar:

    System.out.println("Hello world!");

I'm sure you've done calls like this a million times already, but what's really going on?  out is a static member of the System class; it's a PrintStream object.  A PrintStream is a grandchild of OutputStream in the Java class hierarchy--it has methods implemented that print lines of text at a time as opposed to each character at a time.  System.out is initialized when a program starts to what is known as standard output (stdout).  Stdout is usually the monitor screen, but you can also send stdout to a file at runtime by redirecting it from the Unix command line.  For example, to send the stdout to file "outfile.txt", we do the following:

    % java MyClass > outfile.txt

There is also a System.in class popularly known as standard input (stdin).  Stdin is an InputStream, initially set to taking input from the keyboard, but it can also read from a file at runtime like this:

    % java MyClass < infile.txt

There's a third System i/o file called standard error (stderr).  System.err is another PrintStream designed to direct error messages in case you don't want your output and error messages going to the same place.  Stderr is also initialized to the monitor, but you can redirect it like this:

    % java MyClass >& errfile.txt

And you can combine the redirections:

    % java MyClass < infile.txt > outfile.txt >& errfile.txt

There's lots of other stuff the System class provides for you--check it out.

So what would you do if you wanted to, oh, I don't know, read in an arbitrarily long text file of floating point numbers?


Command-line arguments

Sometimes when running large programs you want to be able to set options about how your program should behave at runtime.  For instance, you might have a hierarchy of debugging statements that you want to suppress at run-time, or you might have a variety of features that you want your users to have access to (check out the manual page for the Unix command "ls"--there's a vast amount of features regarding how to display your data, what to display, ad nauseam).  You can handle this in several ways, but most people make use of command-line arguments to do it.

Remember how all your main functions for your programs have to have the same signature?

        public static void main(String[] argv) { ... }

The array of Strings is where you keep your command-line arguments.  Everything after the class name is included in argv. Let's say we wanted to write a program that just echoed back the command-line arguments to stdout. Here's how we'd do it:

    public class echo {

        public static void main(String[] argv)
        {
            for(int j = 0; j < argv.length; j++)
                System.out.print(argv[j] + " ");  // don't insert an end-line character yet
            System.out.println();  // now print an end-line ('\n')
        }
    }
 



Jim O'Donnell
revised 3/19/00