java—使用线程捕获进程输出

yxyvkwin  于 2021-06-30  发布在  Java
关注(0)|答案(4)|浏览(301)

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

km0tfn4u

km0tfn4u1#

您需要使用process.waitfor()等待进程完成。
此外,您需要同时使用stdout和stderr,以避免阻塞和可能的进程挂起。因此,您需要两个线程来读取这些流,并在流可用时继续读取。
请参阅这篇javaworld文章以获得更多信息和帮助 StreamGobbler 使用标准输出/错误的实现。

gr8qqesn

gr8qqesn2#

你需要有两个线程。一个用来处理i/o,另一个用来等待进程完成(process.waitfor()),并设置一个标志,告诉i/o线程在耗尽数据时退出。

0yg35tkg

0yg35tkg3#

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

v2g6jxz6

v2g6jxz64#

你可以用 VerboseProcess 来自jcabi日志(我是一名开发人员):

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>

相关问题