< Zurück | Inhalt | Weiter >

4.3.1 Java and Standard I/O

Java adopted the UNIX concept of standard I/O (see Section 1.3.1.1). The Linux file descriptors are available to a running Java program as I/O streams via the System class. The System class contains three public static fields


named in, out, and err. You’ve probably already seen out in Java programs with statements like this:


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


You can also write:


System.err.println("Error message here\n");


and


BufferedReader in = new BufferedReader(new

InputStreamReader(System.in)); while ((line = in.readLine()) != null) {

...

}


Java parallels Linux nicely on I/O descriptors. If you redirect any of those file descriptors from the shell command line when you execute a Java program, then that redirected I/O is available to your Java application—with no additional work on your part.

In the example above, if you have System.in all wrapped up into a BufferedReader from which your program is reading lines, then you can run that program as:


$ java MyCode


and it will read input as you type it on your keyboard. This may be how you test your program, but when you put this program to its intended use, you may want it to be able to read from a file. This you can do without any change to the program—thanks to file descriptors, input streams, and redirecting input, for example:


$ java MyCode < file2


which will let the same Java program read from the file named file2 rather than from keyboard.

Your Java program can also set the values of System.in, System.out, and System.err as it executes, to change their destinations.

One common example is changing the destination of System.out, the typical recipient of debugging or logging messages. Say you’ve created a class


or even a whole package of classes that write log messages to System.out (e.g., System.out.println("some message")). Now you realize that you’d like the output to go somewhere else.

You could redirect standard out, as in:


$ java SomeClass > log


but that requires the user to remember to redirect the output every time the program is invoked. That’s fine for testing, or if the output is intended to go to a different place each time it is invoked. But, in this example, we always want the output to go to the same location.

Without changing any of the System.out.println() statements, all the messages can be sent to a new location by reassigning the System.out print stream. The System class has a setter for out—that is, a method which will let you set a new value for out. In your Java program, open the new destination file and give this to the System class:


PrintStream ps = new PrintStream("pathname"); System.setOut(ps);


It will be used from that point forward in the execution of this program as its

out output stream.



CAUTION

Changing standard out (or in, or err) will make the change for all classes from here on in this invocation of the Java runtime—they are static fields of the one System class. Since this is so serious a move, the Java Security Manager (see Section 5.8.4.2) provides a check for setIO to see if the Java program is allowed to make such changes. If such a security manager is in place and you are not allowed to make such changes, an exception (SecurityException) will be thrown. Note also that the permission applies to setting any of the fields; it doesn’t divide the permission into setting one (e.g., out) but not another (e.g., in).

image