在使用SEAndroid时,我从我的Java应用程序中调用Setools命令。它非常适合小型SEAndroid策略,现在我需要用实际的SEAndroid策略来测试我的工具。但不幸的是,我面临一个错误流的问题。
在这里,我以前调用外部命令的代码:
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=)
编辑:
我试着在错误流之前读取输出流,它可以工作。但是,在对输出流执行任何解析之前,我需要检查错误流,所以这个问题仍然是热门话题。
发布于 2014-04-23 18:55:36
首先,最好使用较新的ProcessBuilder类,而不是Runtime。如果您想更进一步,甚至可以使用Apache commons-exec来处理流处理和其他事情。
接下来,正如您已经发现的,在Java中,过程控制是一件棘手的事情,并且遇到了它的一个棘手问题。来自java的Process类的文档:
父进程使用这些流向子进程输入并从子进程获取输出。由于一些本机平台只为标准输入和输出流提供有限的缓冲区大小,如果不及时写入输入流或读取子进程的输出流,可能会导致子进程阻塞,甚至导致死锁。
您需要同时消耗(错误和输出)流,否则就会面临死锁的风险--每个流都应该在各自的线程上读取。使用像StreamGobbler这样的东西(google it,外面有很多)将会是一个很好的一步,或者如果你如此倾向的话,你也可以使用你自己的。要正确处理它并不太困难,但是如果您不熟悉多线程处理,您可能希望查看其他人的实现,或者使用Apache路由。
发布于 2014-11-26 15:57:52
输出的处理非常烦人,以至于我编写了一个名为jproc的库,用于处理使用stdout和stderr的问题。它只需通过如下外部程序过滤字符串:
ProcBuilder.filter("x y z","sed" ,"s/y/a/")它还允许您为完成指定超时,并将非零退出代码转换为异常。
https://stackoverflow.com/questions/23248824
复制相似问题