我正在写一个java程序来读取进程中的错误流。下面是我的代码结构--
ProcessBuilder probuilder = new ProcessBuilder( command );
Process process = probuilder.start();
InputStream error = process.getErrorStream();
InputStreamReader isrerror = new InputStreamReader(error);
BufferedReader bre = new BufferedReader(isrerror);
while ((linee = bre.readLine()) != null) {
System.out.println(linee);
}
如果实际上向被调用进程的错误流写入了任何内容,则上述代码工作正常。但是,如果没有向错误流写入任何内容,则对readLine的调用实际上无限期挂起。但是,我希望使我的代码通用,以便它适用于所有场景。我如何修改我的代码以实现相同的效果呢?
此致,Dev
4条答案
按热度按时间guicsvcw1#
readline()
是一个阻塞调用。它将阻塞直到有一行要读(以行结束字符终止)或底层流关闭(返回EOF)。您需要有检查
BufferedReader.ready()
的逻辑,或者只是使用BufferedReader.read()
,如果您决定等待足够长的时间(或者想做其他事情,然后再次检查)就退出。编辑以添加:也就是说,它不应该“无限期”地保持原样;一旦被调用的进程终止,它应该返回。是否有可能您的被调用进程也输出一些东西到
stdout
?如果是这样的话...您需要也从那里阅读,否则缓冲区将填满,并将阻塞外部进程,这将阻止它退出,这...导致您的问题。dly7yett2#
这是一个迟来的回复,但是这个问题还没有真正解决,它在一些搜索的第一页。我也有同样的问题,
BufferedReader.ready()
仍然会设置一个锁定的情况。如果您需要获取持久流,则以下解决方法将不起作用。但是,如果您只是运行程序并等待其关闭,则这应该是可行的。
我使用的解决方法是调用
ProcessBuilder.redirectError(File)
。然后我读取文件并使用它向用户显示错误流。它工作正常,没有锁定。我确实在Process.waitFor()之后调用了Process.destroyForcibly()
,但这可能是不必要的。下面是一些伪代码:
我希望这至少对您的一些用例有所帮助。
mzsu5hc03#
类似这样的东西也可能工作,并避免阻塞行为(而不需要创建一个文件)
从InputStream的Javadoc.可用
返回可从此输入流读取(或跳过)而不会被此输入流的方法的下一次调用阻塞的字节数的估计值。下一次调用可能是同一线程或另一个线程。单个读取或跳过此字节数不会阻塞,但可能读取或跳过较少的字节。
nsc4cvqm4#
最简单的答案是将错误流重定向到
stdout
: