使用线程捕获进程输出

我正在使用一个线程来捕获进程的流输出,然后将该流输出到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循环有机会对流进行操作之前完成,输出丢失。

您需要使用Process.waitFor()来等待进程完成。

此外,您需要同时使用stdout和stderr以避免阻塞和可能的进程挂起。 因此,您需要两个线程来读取这些流,并在流可用时继续读取。

有关更多信息,请参阅此Javaworld文章 ,以及使用stdout / err的StreamGobbler实现。

您可以使用jcabi-log中的 VerboseProcess (我是开发人员):

 String name = new VerboseProcess( new ProcessBuilder("executable with output") ).stdout(); 

您需要的唯一依赖:

  com.jcabi jcabi-log 0.7.5  

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

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