首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Java运行外部命令时的错误流阻塞

使用Java运行外部命令时的错误流阻塞
EN

Stack Overflow用户
提问于 2014-04-23 15:25:58
回答 2查看 1K关注 0票数 1

在使用SEAndroid时,我从我的Java应用程序中调用Setools命令。它非常适合小型SEAndroid策略,现在我需要用实际的SEAndroid策略来测试我的工具。但不幸的是,我面临一个错误流的问题。

在这里,我以前调用外部命令的代码:

代码语言:javascript
复制
public static BufferedReader runCommand(final String[] args)
            throws IOException {

    BufferedReader stdInput = null;
    BufferedReader stdError = null;
    try {
        Process p = Runtime.getRuntime().exec(args);

        stdInput = new BufferedReader(new
                InputStreamReader(p.getInputStream()));

        stdError = new BufferedReader(new
                InputStreamReader(p.getErrorStream()));

        // read any errors from the attempted command
        String s = null;
        StringBuilder err = new StringBuilder();

        while ((s = stdError.readLine()) != null) {
            err.append(s + "\n");
        }
        if (err.length() != 0) {
            throw new IOException(err.toString());
        }

        return stdInput;
    } finally {
        if (stdError != null) {
            stdError.close();
        }
    }
}

所以,正如您所看到的,我调用一个外部命令。然后读取错误流,如果有任何错误,则抛出一个异常,否则我返回InputStream,以便稍后解析它。

对于实际的SEAndroid策略,错误流似乎是阻塞的(即使我读取了一个字符),并且无法解析命令的结果。如果不读取任何内容就关闭错误流,则应用程序可以正常工作,但如果存在错误,则需要处理错误。如果我在控制台中输入命令,它也可以正常工作。

在第一种情况下(使用小SEAndroid策略),命令的输出很小( ~350行)。在第二种情况下(使用实际的SEAndroid策略),命令的输出更大( >1500行)。

输出流的大小是否可能影响错误流?这两条溪流是两种独特的资源,不是吗?我没有立即读取输出流这一事实有重要意义?

我担心这不是“编程”问题,而是一个系统问题.

有什么建议吗?

谢谢你的help=)

编辑:

我试着在错误流之前读取输出流,它可以工作。但是,在对输出流执行任何解析之前,我需要检查错误流,所以这个问题仍然是热门话题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-23 18:55:36

首先,最好使用较新的ProcessBuilder类,而不是Runtime。如果您想更进一步,甚至可以使用Apache commons-exec来处理流处理和其他事情。

接下来,正如您已经发现的,在Java中,过程控制是一件棘手的事情,并且遇到了它的一个棘手问题。来自java的Process类的文档:

父进程使用这些流向子进程输入并从子进程获取输出。由于一些本机平台只为标准输入和输出流提供有限的缓冲区大小,如果不及时写入输入流或读取子进程的输出流,可能会导致子进程阻塞,甚至导致死锁。

您需要同时消耗(错误和输出)流,否则就会面临死锁的风险--每个流都应该在各自的线程上读取。使用像StreamGobbler这样的东西(google it,外面有很多)将会是一个很好的一步,或者如果你如此倾向的话,你也可以使用你自己的。要正确处理它并不太困难,但是如果您不熟悉多线程处理,您可能希望查看其他人的实现,或者使用Apache路由。

票数 1
EN

Stack Overflow用户

发布于 2014-11-26 15:57:52

输出的处理非常烦人,以至于我编写了一个名为jproc的库,用于处理使用stdout和stderr的问题。它只需通过如下外部程序过滤字符串:

代码语言:javascript
复制
ProcBuilder.filter("x y z","sed" ,"s/y/a/")

它还允许您为完成指定超时,并将非零退出代码转换为异常。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23248824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档