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

时间:2009-07-06 20:01:56

标签: java io

我正在尝试开发一个读取外部程序标准输出的类(使用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);
    }
    //...

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

5 个答案:

答案 0 :(得分:7)

同时使用程序的stdout和stderr来避免阻塞场景。

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

答案 1 :(得分:2)

在这种情况下,你应该有单独的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()阻止。

答案 2 :(得分:1)

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

接下来,您说在此过程中需要用户输入 - 您是否通过写入stdin提供任何用户输入?如果它正在等待输入,您应该适当地写入stdin并刷新它。

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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

不写入输出(即执行程序的标准输入)导致输入(即来自执行程序的输出)不被完全捕获。写信给它会拖延这个过程。

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