Programming Tools & Computer Science I

CSC 185 & 201, Spring 2013, Northern Virginia Community College

Week 5: I/O redirection (185)

2013-02-13

All programs have access to 3 standard streams, which when run on the command line behave as follows by default:

You can control the behavior of those streams using redirection, which can change the source of stdin, or the destination of stdout or stderr.

We'll work with examples in Microsoft Windows, but the same ideas and most of the same syntax work in Linux or OSX (usually more consistently and with more powerful features); later in the semester we'll cover the command line interfaces available on those systems (or something similar).

Output redirection

Rather than printing to the console, you can signal that output (stdout) should go to a named file by using the > operator. The following example lists the contents of C:\ into a file:

dir /b C:\ > c-contents.txt

Note that if there is no output, an empty file will be created. In either case, any existing file named c-contents.txt will be destroyed. If you want to add on to the file rather than overwrite it, use the >> operator:

dir /b C:\ >> c-contents.txt

Now the output from that dir command will be appended to the file if it already exists (otherwise it will be created just like the first case).

You can also redirect stderr; for example, the following command lists the contents of C:\XYZ into a file, and saves any error output into another file. There will probably be error output, unless you happen to have a directory named XYZ.

dir /b C:\XYZ > xyz-contents.txt 2> xyz-errors.txt

On earlier versions of Windows, redirection of stderr might not be available.

Input redirection

You can signal to a program that its input should come from a file (rather than the keyboard) by using the < operator.

For an example, let's look at the find command (Windows version). This command searches its input for a target string, and prints lines where it finds the target. For example, find "banana" will print back all the lines that you type that contain "banana" (quotes not necessary). Note that when you run the command, you'll need a way to signal that you're done. On the Windows command line, type Ctrl-Z and then Enter to signal end-of-file.

That's probably not very useful, since when you're typing you already know yourself which lines contain "banana". The command is really made to search through files, and you can send input from a file by redirection:

find "banana" < banana-info.txt

The above command will print all lines in banana-info.txt that contain the word "banana".

Pipes

Finally, you might want to get output from one program and send it directly to another; so you combine output and input redirection. This is called piping output, and uses the pipe character (|) as the operator.
Here's an example:

dir /b C:\Windows\System32 | find "reg"

That particular example could be accomplished more simply by using a wildcard (dir /b C:\Windows\System32\*reg*), but in general pipes provide a powerful way to combine programs to gain new functionality.

In Java

Java programs work with I/O redirection just like any other program. Here's an example that counts words read from stdin:


import java.io.IOException;
    
class WordCount {
    public static void main(String[] args) throws IOException {
        boolean inWord = false; // flag to indicate we're reading a word
        int count = 0; // current word count
        int c; // current letter
        while ((c = System.in.read()) != -1) {
            // If we hit a space, add to count if we have seen a word
            if (Character.isWhitespace(c)) {
                if (inWord) {
                    count++;
                    inWord = false;
                }
            } else {
                inWord = true;
            }
        }
        System.out.println(count);
    }
}

To use with a file as input, compile and run

java WordCount < FILE.txt

Other readings