从外部进程读取输出

Posted

技术标签:

【中文标题】从外部进程读取输出【英文标题】:Read output from external process 【发布时间】:2012-04-30 11:41:22 【问题描述】:

我正在尝试运行 .csh 脚本并将其输出读入 StringBuffer。 尽管从控制台运行脚本会返回一些输出,但输出有时会返回空。相同的运行流程有时会返回输出,有时则不会,尽管进程启动的方式没有任何改变(相同的脚本、路径、参数)并且脚本也没有改变。 我没有抛出任何异常。 什么可能导致现在正确/成功读取输出? 代码段是

public static String getOutpoutScript(Process p) 
    InputStream outpout = p.getInputStream();
    logger.info("Retrived script output stream");
    BufferedReader buf = new BufferedReader(new InputStreamReader(outpout));
    String line = "";
    StringBuffer write = new StringBuffer();

    try 
        while ((line = buf.readLine()) != null) 
            write.append(line);
        
     catch (IOException e) 
        // do something
    

    return write.toString().trim();


除了不关闭流不好的事实之外,代码中的这个或其他内容是否可能会在某些情况下阻止输出被正确读取?

谢谢,

【问题讨论】:

你有没有调试过p.getInputStream()总是一样的,output分配正确? 可能和***.com/questions/10365402/…一样的问题 【参考方案1】:

如果您使用 ProcessBuilder 启动它,您可以combine the error stream into the output stream. 这样,如果程序打印到 stderr,您也会捕获它。或者,您可以同时阅读两者。此外,您可能不想使用 readLine,如果程序没有在末尾打印行尾字符,您可能会卡住一段时间。

【讨论】:

脚本输出始终采用相同的格式(4 行,每行 5 个单词)。所以 readLine 似乎不是问题。我会尝试阅读错误流。谢谢。【参考方案2】:

也许您必须将p.getInputStream() 替换为p.getOutputStream()

除此之外,有时进程可能会阻塞等待输入,因此您必须异步读写 - 一种可能的解决方案是使用不同的线程 - 例如一个线程在读,另一个在写,一个在监控进程。

【讨论】:

他可以在errorstream和inputstream之间切换。但是在这种情况下切换到输出流没有任何意义 它令人困惑,但 InputStream 是 Java 的 InputStream,但程序的输出流(反之亦然) 您需要从您的角度而不是流程来查看流',如果您想在某处写入(创建输出),请使用输出流,如果您想阅读(获取输入),使用输入流【参考方案3】:

如果出现错误,默认情况下会写入 getErrorStream()。如果您有问题,我会确保您在某处阅读此内容。

如果此流的缓冲区已满,您的程序将停止,等待您读取它。

解决这些问题的一种简单方法是使用ProcessBuilder.redirectErrorStream(true)

【讨论】:

以上是关于从外部进程读取输出的主要内容,如果未能解决你的问题,请参考以下文章

Erlang:控制Erlang进程崩溃时如何使连接的外部OS进程自动死亡?

Perl - 从外部进程直接输出到标准输出(避免缓冲)

从异步子进程读取流输出

从Python中的imagemagick子进程读取输出[重复]

从 Python 调用带有“子进程”的 Java 应用程序并读取 Java 应用程序输出

QT软件开发: QProcess启动进程完成交互并获取输出