Translation: Cherami Email:cherami@163.net Original: http://developer.java.sun.com/developer/TechTips/2000/tt0815.html
If you often use UNIX or Windows shells (command processor), you may often use I/O redirection like this: $ command >outfile This usage is: Run a command and direct its standard output (such as System.out.println output) to the specified file rather than to the console or screen. This feature is very useful. This can also be achieved in Java programs without having to rely on the shell. Typically if you use a programming style that relies on standard input output (like the Unix shell and other toolkits), you may not need or want to redirect in the program. But sometimes you want to, let's look at a few examples. The first example redirects the standard output to a file: Import java.io.*; public class RedirectDemo1 { public static void Main (String args[]) throws IOException { Create a printstream on the file FileOutputStream fos = New FileOutputStream ("OUT.txt"); Bufferedoutputstream BOS = New Bufferedoutputstream (FOS, 1024); PrintStream PS = New PrintStream (Bos, FALSE); REDIRECT System.out to this file System.setout (PS); Output System.out.println ("This is a test/u4321"); int n = 37; System.out.println ("The square of" + N + "Is" + (n * n)); Ps.close (); } }
Standard output (System.out) is a reference to a PrintStream object. To redirect output, create an object that represents a file or other output stream (for example, a network connection). Then use the System.setout call to change the System.out reference. The Java.lang.System code implemented in JDK 1.3 is in this form: FileOutputStream fdout = New FileOutputStream (filedescriptor.out); SetOut0 (New PrintStream ( New Bufferedoutputstream (Fdout, 128), true); This code initializes the System.out. Therefore, by default, System.out is a printstream, which is a FileOutputStream file created from Filedescriptor.out with a 128-byte buffer. Automatic refresh (auto output when a new line character or byte vector is encountered). When the output is redirected like the above, System.out becomes a reference to a newly created PrintStream object that is passed in using System.setout. RedirectDemo1 has several problems, first of all, the PrintStream uses the platform default character encoding to convert characters to bytes. This is usually a good thing, for example, if you have a line in your applet: System.out.println ("This is a Test"); And you run the program in the United States: $ java Prog >outfile The program deposits ASCII characters in the file "outfile". This may be the 7-bit ASCII text file you want to get. But if there is a Unicode character '/u4321 ' in the program, it will be converted to a '? '. If you look at the file, can you see it? In other words, the default encoding does not correctly process that output character. Another problem is that I/O redirection can be generalized, for example, you can direct output to a string rather than a file. Here's an example that includes two questions: Import java.io.*; public class RedirectDemo2 { public static void Main (String args[]) throws IOException { Establish a printwriter on the StringWriter. StringWriter SW = new StringWriter (); PrintWriter pw = new PrintWriter (SW); Output some things to StringWriter Pw.println ("This is a test/u4321"); int n = 37; Pw.println ("The square of" + N + "is" + (n * n)); Get the string that was written String str = sw.tostring (); Explicit it System.out.print (str); Output a string to a file, using UTF-8 encoding FileOutputStream fos = New FileOutputStream ("OUT.txt"); OutputStreamWriter OSW = New OutputStreamWriter (FOS, "UTF-8"); BufferedWriter BW = New BufferedWriter (OSW); Bw.write (str); Bw.close (); Read back the string and check FileInputStream FIS = New FileInputStream ("OUT.txt"); InputStreamReader ISR = New InputStreamReader (FIS, "UTF-8"); BufferedReader br = New BufferedReader (ISR); String S1 = Br.readline (); String s2 = br.readline (); Br.close (); String linesep = System.getproperty ("Line.separator"); if (!str.equals (s1 + linesep + s2 + linesep)) System.err.println ("Equals check failed"); } }
The first part of the example creates a PrintWriter object on a stringwriter that is similar to PrintStream, but operates on characters rather than byte streams. StringWriter is used to aggregate characters into a dynamic internal buffer and revert to a string or stringbuffer later. After the output is written to StringWriter, the clustered string is restored, and the string is written to the file using OutputStreamWriter and UTF-8 encodings. This encoding is supported in all Java implementations. It encodes characters in the range '/u0001 ' to '/u007f ' as one byte while the other characters are two or three bytes. Finally, the string is read back from the file, or the UTF-8 encoding is used. Then compare it with the original string. There are two line delimiters in the original string, so the two strings are read back, and row separators are added for comparison purposes. Note that you can also redirect input from a file or string, using a class such as StringReader. |