Call other programs from the Java program
http://developer.java.sun.com/developer/techtips/1999/tt1214.html Discussed how RMI (Remote Method Invocation, Remote Method Call) is used for program communication, and the other for communication is Runtime. EXEC () method. You can use this method from a run a Java program to call another program. Runtime.exec also allows you to perform and programs related operations, such as the standard input and output of the control program, waiting for the end of the program and get its exit status. Below is a simple C program used to illustrate these features:
#include
Int main () {
Printf ("Testing / N");
Return 0;
}
This program writes "Testing" to the standard output and then terminates the program with an exit status 0.
In order to perform this simple program in the Java program, compile this C program first:
$ cc Test.c -o test
(Translator Note: For Linux users, you can use GCC Test.c -o Test, and WINDOWS users can be compiled into executable program Test.exe with the corresponding C language compiler.
(Your C compiler may require different parameters) and then use the following code to call the program:
Import java.io. *;
Import java.util.arraylist;
Public class execdemo {
Static Public String [] Runcommand (String CMD)
THROWS IOEXCEPTION {
// set up list to capture command output Lines
ArrayList List = New ArrayList ();
// start command running
Process proc = runtime.getRuntime (). EXEC (CMD);
/ ** Translator Note: The previous statement should be changed to java.lang.process, namely:
Java.lang.Process Proc = runtime.getRuntime (). EXEC (CMD);
If you don't change, you may compile differently. Use JDK1.2 on the translator's machine, and compile 5 errors.
4 errors occurring using JDK1.4
* /
// Get Command's Output Stream and
// put a buffered reader input stream on it
InputStream istr = proc.getinputstream ();
BufferedReader Br =
New BufferedReader (ISTR);
// read Output Lines from Command
String Str;
While ((str = br.readline ())! = NULL)
List.Add (STR);
// Wait for Command to Terminate
Try {
Proc.waitfor ();
}
Catch (InterruptedException E) {
System.err.Println ("Process Was Interrupted");
}
// check its exit value
IF (Proc.exitValue ()! = 0)
System.err.Println ("exit value was non-zero); // Close Stream
br.close ();
// Return List of strings to Caller
Return (String []) list.toarray (new string [0]);
}
Public static void main (string args []) throws oException {
Try {
// Run a command
String Outlist [] = Runcommand ("Test");
// Display ITS OUTPUT
For (int i = 0; i System.out.println (Outlist [i]); } Catch (IOException E) { System.err.Println (e); } } } Demonstration Program Call Method RunCommand actually runs the program. String Outlist [] = Runcommand ("Test"); This method uses an output stream of the input stream hook, so it can read the output of the program and store it into a string list. InputStream istr = proc.getinputstream (); BufferedReader Br = New BufferedReader (ISTR); String Str; While ((str = br.readline ())! = NULL) List.Add (STR); After all the outputs are read, call the WaitFor Waiter to terminate, and then call the exit status value of the ExitValue read the program. If you have done a lot of system programming, such as UNIX system calls, you should be familiar with this method. (This example assumes that the current path is included on your SHELL execution path). If you use UNIX systems, you can use: RunCommand ("ls -l"); instead: Runcommand ("Test"); (Translator Note: A more common is Runcommand ("java"); the translator uses Runcommand ("Dir"); the result obtained under Windows2000 is the program IO is abnormal, and there is no test under the Linux system.) Get long list of all files under the current path. But use this method to get a list highlight a basic weakness using Runtime.exec - the program you call becomes non-portable. That is, Runtime.exec is portable, existed in different Java implementations, but is not necessarily the case being called, and there is no program "LS" under the Windows system. Suppose you run Windows NT and you decide Runcommand ("DIR"); Correct this problem, "DIR" is the equivalent command of "LS". This can't work because "DIR" is not an executable program. It built in the shell (command interpreter) cmd.exe. So you should use: Runcommand ("CMD / C Dir"); Here "CMD / C Command" is "calling the shell and executes the specified command and exits." Similarly, for a UNIX shell, such as a Korn shell, you may use: Runcommand ("Ksh -c alias"); Here "Alias" is the built-in command of the shell. The output in this case is a list of the aliahe of the shell. In the example of getting a list of directory lists, you can reach the same result with portable Java programs. E.g: Import java.io.file; PUBLIC CLASS DUMPFILES { Public static void main (string args []) { String List [] = new file ("."). List (); For (int i = 0; i System.out.println (List [i]); } } Give a list of all files and directories in the current directory. Therefore, in most cases, it is meaningless to use LS / DIR. One case that makes sense using Runtime.exec is to allow users to specify an editor or text handler (like Emacs or VI or Word) editing files. This is a usual feature of large programs. The program will have a configuration file specify the local path of the editor, and then use this path to call Runtime.exec. A subtle place for Runtime.exec is how it looks for files. For example, you are using: Runtime.exec ("ls"); So how to find "LS"? Tests on JDK 1.2.2 show that it is to search for PATH environment variables. This happens when you execute commands in the shell. But there is no explanation in the document, so it should be careful. You can't assume that the search path has been set. Just as discussed above, use Runtime.exec using runtime.exec to use the absolute path. There are also different runtime.exec allows you to specify an array of environmental strings. (Translator Note: See the API documentation in a specific way).