tags:

views:

550

answers:

5

How can I write a program in Java that will execute another program? Also, the input of that program should be given from our program and the output of that program should be written into a file.

This is my small set of code to get its output:

Process p = Runtime.getRuntime().exec("C:\\j2sdk1.4.0\bin\\helloworld.java");
BufferedReader input =
        new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) 
  System.out.println(line);

input.close();

This was my set of code but this throws an IOException.

+1  A: 

What platform are you in?

If you are on *nix you can type:

java MyProgram | myexternalprogram > myfilename.txt

Spence
+2  A: 

You can use java.lang.Process and java.lang.ProcessBuilder. You interact with the input/output of the process using getInputStream/getOutputStream/getErrorStream.

However, there's an Apache Commons library called Exec which is designed to make all of this easier. (It can normally get quite hairy when it comes to quoting command line parameters etc.) I haven't used Exec myself, but it's worth checking out.

Jon Skeet
+3  A: 

The API that Java offers for this is the ProcessBuilder. It is relatively straightforward to set working directory and pass parameters.

What is a little tricky is passing STDIN and reading STDERR and STDOUT, at least for non-trivial sizes thereof, because you need to start seperate threads to make sure the respective buffers get cleared. Otherwise the application that you called might block until it can write more output, and if you also wait for that process to finish (without making sure that STDOUT gets read), you will deadlock.

Thilo
+1 for the reading from separate threads to avoid deadlock.
Jon Skeet
+3  A: 

When you only want to start other programms, you can use the exec method like this:

Runtime r = Runtime.getRuntime();
mStartProcess = r.exec(applicationName, null, fileToExecute);

StreamLogger outputGobbler = new StreamLogger(mStartProcess.getInputStream());
outputGobbler.start();

int returnCode = mStartProcess.waitFor();


class StreamLogger extends Thread{

   private InputStream mInputStream;

   public StreamLogger(InputStream is) {
        this.mInputStream = is;
    }

   public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(mInputStream);
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                    System.out.println(line);
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

}

exec:

public Process exec(String command, String envp[], File dir) 



   @param      command   a specified system command.
   @param      envp      array of strings, each element of which 
                         has environment variable settings in format
                         <i>name</i>=<i>value</i>.
   @param      dir       the working directory of the subprocess, or
                         <tt>null</tt> if the subprocess should inherit
                         the working directory of the current process.
Markus Lausberg
+1  A: 

Please do not edit your question so that it does not fit the original answers anymore. If you have follow-up question, clearly mark them as such, or ask them as a seperate questions, or use comments or something.

As for your IOException, please give the error message it shows.

Also, it seems as if you are trying to run a ".java" file directly. That will not work. The methods described here are to launch native binary executables. If you want to run a ".java" file, you have to compile it to a class, and the invoke that class' main method.

Thilo