Java使用inputstream从外部程序读取标准输出

我正在尝试开发一个读取外部程序标准输出的类(使用Process,Runtime.getRuntime()。exec(cmdLine,env,dir)的实例)。 程序在过程中接受用户输入,并且在给出有效输入之前不会继续; 这似乎导致我尝试读取其输出的方式出现问题:

egm.execute(); // run external the program with specified arguments BufferedInputStream stdout = new BufferedInputStream(egm.getInputStream()); BufferedInputStream stderr = new BufferedInputStream(egm.getErrorStream()); BufferedOutputStream stdin = new BufferedOutputStream(egm.getOutputStream()); int c; //standard output input stream int e; //standadr error input stream while((c=stdout.read()) != -1) //<-- the Java class stops here, waiting for input? { egm.processStdOutStream((char)c); } while((e=stderr.read()) != -1) { egm.processStdErrStream((char)e); } //... 

我该如何解决这个问题,以便程序接收有效的输入并继续? 解决这个问题的任何帮助都会很棒!

必须同时使用程序的stdout和stderr以避免阻塞方案。

有关详细信息,请参阅此文章 ,特别注意在单独的线程中捕获stdout / err的StreamGobbler机制。 这对于防止阻塞至关重要,如果您没有正确执行,则会导致大量错误!

在这种情况下,您应该有单独的Threads读取InputStream和ErrStream。

你也可以想做类似的事情:

 public void run() { while( iShouldStillBeRunning ) { int c; while( stdout.available() > 0 && ((c=stdout.read()) != -1)) { egm.processStdOutStream((char)c); } Thread.sleep(100); } } 

因为在输入之前你会在stdout.read()上被阻塞。

首先,如果它正在写入错误流并且已经耗尽了缓冲区,则可能会阻塞 – 在输出流完全完成之前,您不会从错误流中读取。

接下来,你说它在进程中需要用户输入 – 你是否通过写入stdin 它任何用户输入? 如果它正在等待输入,你应该适当地写入stdin ,然后冲洗它。

你没有在你的问题中说你试图运行它时实际发生了什么。 请更新详细说明发生的情况,以及您希望发生的情况。 告诉我们命令是什么的奖励点。

另外,这是UNIX / Linux还是Windows? 如果这是UNIX / Linux(或其他一些POSIX平台),出于安全原因,程序可能会在/ dev / console而不是/ dev / stdin上查找输入。

为了其他人寻找这类问题的解决方案的好处,我只想补充一点,我有一个非常类似的问题。 但就我而言,该计划也在等待一行输入。 因此需要涉及三个线程来异步处理所有三个通道。

在不写入输出(即执行程序的标准输入)的情况下,不会完全捕获输入(即来自执行程序的输出)。 写信给它绞死了这个过程。

解决方案是Jon Skeet的三个词:“并冲洗它”。 添加刷新后,没有挂起。 谢谢!