使用线程捕获进程输出

3

我正在使用一个线程来捕获进程的流输出,然后将该流输出到Eclipse控制台。我有一个问题,就是何时终止执行流输出的线程。

Thread t = new Thread(new Runnable(){
        private boolean isProcessDone(Process p)
        {
            //not sure what to do here
        }
        public void run()
        {
            Process p = Runtime.getRuntime().exec("executable with output");
            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
            BufferedReader error = new BufferedReader (new InputStreamReader(p.getErrorStream()));
            while ( !isProcessDone(p) ) {
                String line;
                if( (line = input.readLine()) != null )
                {
                    System.out.println(line);
                }
                if( (line = error.readLine()) != null )
                {
                    System.out.println(line);
                }
            }
            input.close();  
            error.close();      
        }
    });
    t.start();

我的问题是isProcessDone()函数应该放什么内容。我参考的例子使用了流的ready()函数,但我不确定这是否适用于只使用std::err和std::out其中之一的程序。我也尝试过使用。
try{
    p.exitValue();
    return true;
}catch(IllegalThreadStateException e){}
return false;

但是在 while 循环有机会处理流之前,线程已经完成了,输出被丢失。

4个回答

8
你需要使用 Process.waitFor() 方法来等待进程完成。
此外,你需要同时消耗 stdout 和 stderr 以避免阻塞和可能的进程挂起。因此,你需要两个线程来读取这些流,并在流可用时继续读取。
请参见 这篇 Javaworld 文章 获取更多信息以及一个用于消耗 stdout/err 的 StreamGobbler 实现。

我不想在发送此任务时挂起主进程;这就是为什么我要在一个线程中执行它。你是说我需要多个线程来处理这个任务吗? - Adrian Park
如果您尝试消耗stout然后stderr,或者stderr然后stdout(即不同时),则可能会遇到阻塞行为,这取决于输出的数量。因此,无论在新线程中生成进程,您都需要在单独的线程中消耗stdout/err。 - Brian Agnew
感谢您对一个(非常)令人困惑的Java实现进行了清晰的解释。 - C. Ross

2
你可以使用 VerboseProcessjcabi-log(我是一个开发者)中使用:
String name = new VerboseProcess(
  new ProcessBuilder("executable with output")
).stdout();

你需要的唯一依赖:
<dependency>
  <groupId>com.jcabi</groupId>
  <artifactId>jcabi-log</artifactId>
  <version>0.7.5</version>
</dependency>

1
你需要有两个线程。一个用于处理I/O,另一个等待进程完成(Process.waitFor()),并设置一个标志告诉I/O线程在耗尽数据时退出。

0

您需要在单独的线程中处理读取输出,这里有一个示例在这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接