7

我正在编写一个 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 的调用实际上会无限期挂起。但是,我想让我的代码通用,以便它适用于所有场景。如何修改我的代码以实现相同的目标。

问候,开发

4

2 回答 2

3

readline()是阻塞调用。它将阻塞,直到有一行要读取(由行尾字符终止)或底层流关闭(返回 EOF)。

如果您决定等待足够长的时间(或者想要做其他事情然后再次检查),您需要有正在检查BufferedReader.ready()或只是使用和救助的逻辑。BufferedReader.read()

编辑添加:话虽如此,它不应该“无限期地”按原样挂起;一旦调用的进程终止,它应该返回。有没有机会您调用的进程也输出一些东西到stdout?如果是这种情况......您也需要从中读取,否则缓冲区将填满并阻止外部进程,这将阻止它退出......导致您的问题。

于 2012-10-16T06:34:34.817 回答
2

这是一个迟到的回复,但问题并没有真正解决,它在一些搜索的第一页上。我有同样的问题,并且BufferedReader.ready()仍然会设置它会锁定的情况。

如果您需要获取持久流,则以下解决方法将不起作用。但是,如果您只是在运行一个程序并等待它关闭,这应该没问题。

我正在使用的解决方法是调用ProcessBuilder.redirectError(File). 然后我会读取该文件并使用它向用户呈现错误流。它工作正常,没有锁定。我确实Process.destroyForcibly()在 Process.waitFor() 之后打电话,但这可能是不必要的。

下面的一些伪代码:

    文件 thisFile = new File("somefile.ext");
    ProcessBuilder pb = new ProcessBuilder(yourStringList);
    pb.redirectError(thisFile);
    进程 p = pb.start();
    p.waitFor();
    p.destroyForcely();
    ArrayList fileContents = getFileContents(thisFile);

我希望这至少对您的一些用例有所帮助。

于 2015-10-07T15:11:27.873 回答