开发者

Execute external process from java. Got the output after the process terminated, but need it before termination

开发者 https://www.devze.com 2023-03-21 10:29 出处:网络
Why I get the output of the process after the process has terminated? I need to get the process output \"live\", while the process is running and not after the process has terminated. I would like to

Why I get the output of the process after the process has terminated? I need to get the process output "live", while the process is running and not after the process has terminated. I would like to run a process like a jboss, which is logging on the standard output, so I need that information in time, and not after the process has terminated. Thank you for answers.

Here is my code:

        try {
        process = processBuilder.start();
        processOutput = process.getOutputStream();
        processInput = process.getInputStream();
        processReader = new BufferedReader(new InputStreamReader(
                processInput));
        processWriter = new BufferedWriter(new OutputStreamWriter(
                processOutput));

        while ((line = processReader.readLine()) != null) {
            System.out.println(line);
          }
        processReader.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Extension:

So I would like to run an external program from an eclipse plug-in with a button. When I click to the button, the program start and the output of the external program will go back to the console. When I click to the stop, the program stops. So here is how I make the instance of the process builder. And I made an example class to test the process builder without start the whole plugin project in every modification.

Here is my process builder instance which is implements the Runnable:

@Override
public void run() {
    List<String> command = new ArrayList<String>();
    command.add(serverPath);
    command.add(String.valueOf(count));
    command.add(filePath);
    processBuilder = new ProcessBuilder(command);
    processBuilder.redirectErrorStream(true);

    try {
        process = processBuilder.start();
        processOutput = process.getOutputStream();
        processInput = process.getInputStream();
        processReader = new BufferedReader(new InputStreamReader(
                processInput));
        processWriter = new BufferedWriter(new OutputStreamWriter(
                processOutput));

        System.out.println(process.waitFor());
        while ((line = processReader.readLine()) != null) {
            System.out.println(line);

        }
        processReader.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        /开发者_Go百科/ TODO Auto-generated catch block
        e.printStackTrace();
    }

}

The parameters are come in the constructor. And here is the instantiation:

public static void main(String[] args) throws Exception

{

 SimulationProcess smp = new SimulationProcess(count, "file",
            "program_name");
    smp.run();

}


There are a few things you can try to resolve your issue:

a) Make a test program and run it with your above code to ensure you can read it properly. For example:

public static void main(String[] args) {
  for(;;) {
    try {
      Thread.sleep(5000);
      System.out.println("Test output");
    } catch(InterruptedException e) {
      // Ignore
    }

  }
}

b) Make sure you are handling the process' error stream - the process can lock up if you do not handle the error stream. Look at this site for a tutorial on the things to avoid while using Java's ProcessBuilder or Runtime.exec() - it includes an implementation of a StreamGobbler that will throw away all data on a stream you don't care about.

c) Try using System.out.flush() - it may be that your output is being buffered.

EDIT: Thanks for the update. Your problem is here:

System.out.println(process.waitFor()); // Waits for the process to exit.
while ((line = processReader.readLine()) != null) {
    System.out.println(line);
}

If you remove the waitFor() it will keep printing until the stream closes. The stream should only close if the process dies. You should put the waitFor() after the loop?


Maybe your output does not contain a newline character, that way your while-loop won't do anything until the process is finished.

Try it using another read method which does not wait for a newline-character, for example:

char[] cbuf = new char[10];
while(processReader.read(cbuf) != -1)
{
  System.out.print(cbuf);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消