views:

156

answers:

2

Hi all:

1) I'm using Java to call Linux terminal to run foo.exe and save the output in a file:

    String[] cmd = {"/bin/sh", "-c", "foo >haha.file"};
    Runtime.getRuntime().exec(cmd);

2) The problem is when I plan to read haha.file later in the code, it hasn't been written yet:

File f=new File("haha.file"); // return true
in = new BufferedReader(new FileReader("haha.file"));
reader=in.readLine();
System.out.println(reader);//return null

3) Only after the program is done will the haha.file be written. I only know how to flush "Writers" but don't know how to flush sth. like this. How can I force java to write the file in the terminal?

Thanks in advance E.E.

A: 

You can either wait for the completion of the process:

Process p = Runtime.getRuntime().exec(cmd);
int result = p.waitFor();

Or use the p.getInputStream() to read directly from the standard output of the process.

Maurice Perry
+1  A: 

This problem is caused by the asynchronous nature of Runtime.exec. foo is being executed in a seperate process. You need to call Process.waitFor() to insure the file has been written.

String[] cmd = {"/bin/sh", "-c", "foo >haha.file"};
Process process = Runtime.getRuntime().exec(cmd);
// ....
if (process.waitFor() == 0) {
    File f=new File("haha.file");
    in = new BufferedReader(new FileReader("haha.file"));
    reader=in.readLine();
    System.out.println(reader);
} else {
    //process did not terminate normally
}
dbyrne
Be careful with this approach. There are nasties lurking with the stdout/stderr stream when using exec(). You really need to ASYNCHRONOUSLY consume the output/error streams while waitFor() is blocking otherwise it may never return because the stdout/err buffers fill up and block the forked processes. Checkout apache commons-exec for a lib that solves this.
Mike Q