ivan
ivan

Reputation: 297

Java - Read process output when it's finished

I have a problem in my code

ProcessBuilder pb = new ProcessBuilder("my program.exe","-g");
Process core = pb.start();
if(!core.waitFor(5, TimeUnit.HOURS))
{
    isDestroyed = true;
    core.destroy();
}
else
    isDestroyed = false;

String xmlOutput = IOUtils.toString(core.getInputStream());

And the problem is that it works all the time exactly 5 hours, but when I run it from console, it works <10 seconds. What's the problem? OS is Windows 8.1 64bit.

I want it runs the same time as from console. Or there is another good way to get output? If yes, please say how. Thanks

Upvotes: 2

Views: 3476

Answers (3)

user4910279
user4910279

Reputation:

Consume the process's STDOUT in another thread. And main thread waits for the process terminattion.

    ProcessBuilder pb = new ProcessBuilder("my program.exe","-g");
    Process core = pb.start();
    InputStream stream = core.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
    StringBuilder stringBuilder = new StringBuilder();
    new Thread(() -> {
        try {
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
        } catch (IOException ex) {
        }
    }).start();;
    if(!core.waitFor(5, TimeUnit.HOURS)) {
        isDestroyed = true;
        core.destroy();
    } else
        isDestroyed = false;

Upvotes: 0

You can have your process return its output while it's processing:

ProcessBuilder pb = new ProcessBuilder("my program.exe","-g");
Process core = pb.start();
InputStream stream = core.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
StringBuilder stringBuilder = new StringBuilder();
long end = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(5);

while (System.currentTimeMillis() < end && (line = reader.readLine()) != null) {
    stringBuilder.append(line);
}
stream.close();
String xmlOutput = stringBuilder.toString();

Upvotes: 1

user207421
user207421

Reputation: 310916

You're deadlocked for 5 hours waiting for the process to exit while it is waiting for you to consume some input so it won't be blocked producing it so it can exit.

You should consume the input first, and then do the waitFor().

NB You also need to close the output stream to the process so it isn't waiting for input.

Upvotes: 0

Related Questions