我正在编写一个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的调用实际上会无限期挂起。然而,我想使我的代码通用,以便它适用于所有场景。如何修改我的代码以实现同样的效果。
谨致问候,开发
readline()
是一个阻塞调用。它将阻塞,直到有一行要读取(以行尾字符结束)或关闭底层流(返回EOF)。
你需要有一个逻辑来检查BufferedReader.ready()
,或者只是使用BufferedReader.read()
,如果你决定等待足够长的时间(或者想做其他事情,然后再次检查),就退出。
编辑以添加:也就是说,它不应该"无限期"挂起;一旦被调用的进程终止,它就应该返回。您调用的进程是否也向stdout
输出了一些东西?如果是这样的话。。。你也需要从中读取,否则缓冲区将填充并阻止外部进程,从而阻止它退出。。。导致你的问题。
这是一个延迟回复,但问题并没有真正解决,它出现在一些搜索的第一页上。我遇到了同样的问题,BufferedReader.ready()
仍然会设置一个锁定的情况。
如果需要获得持久流,以下解决方法将不起作用。然而,如果你只是在运行一个程序并等待它关闭,这应该没问题
我使用的解决方法是调用ProcessBuilder.redirectError(File)
。然后我会读取该文件,并使用它向用户显示错误流。它工作得很好,没有锁住。我确实在Process.waitFor()之后调用了Process.destroyForcibly()
,但这可能是不必要的。
下面的一些伪代码:
File thisFile=新文件("somefile.ext");ProcessBuilder pb=新的ProcessBuilder(您的StringList);pb.redirectError(thisFile);进程p=pb.start();p.等待();p.destroyForcebly();ArrayList fileContents=getFileContents(thisFile)
我希望这至少对您的一些用例有所帮助。
类似的东西也可以工作,并避免阻塞行为(无需创建文件)
InputStream error = process.getErrorStream();
// Read from InputStream
for (int k = 0; k < error.available(); ++k)
System.out.println("Error stream = " + error.read());
从InputStream.available 的Javadoc
返回可以从此输入流读取(或跳过)的字节数的估计值,而不需要为此输入流执行下一个方法的阻塞。下一个调用可能是同一个线程,也可能是另一个线程。这么多字节的一次读取或跳过不会阻塞,但可能会读取或跳过更少的字节。
最简单的答案是简单地将错误流重定向到stdout
:
process.getErrorStream().transferTo(System.out);