java 正在从进程阅读错误流

1szpjjfi  于 2023-01-24  发布在  Java
关注(0)|答案(4)|浏览(93)

我正在写一个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

guicsvcw

guicsvcw1#

readline()是一个阻塞调用。它将阻塞直到有一行要读(以行结束字符终止)或底层流关闭(返回EOF)。
您需要有检查BufferedReader.ready()的逻辑,或者只是使用BufferedReader.read(),如果您决定等待足够长的时间(或者想做其他事情,然后再次检查)就退出。

编辑以添加:也就是说,它不应该“无限期”地保持原样;一旦被调用的进程终止,它应该返回。是否有可能您的被调用进程也输出一些东西到stdout?如果是这样的话...您需要也从那里阅读,否则缓冲区将填满,并将阻塞外部进程,这将阻止它退出,这...导致您的问题。

dly7yett

dly7yett2#

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

如果您需要获取持久流,则以下解决方法将不起作用。但是,如果您只是运行程序并等待其关闭,则这应该是可行的。

我使用的解决方法是调用ProcessBuilder.redirectError(File)。然后我读取文件并使用它向用户显示错误流。它工作正常,没有锁定。我确实在Process.waitFor()之后调用了Process.destroyForcibly(),但这可能是不必要的。
下面是一些伪代码:

File thisFile = new File("somefile.ext");
    ProcessBuilder pb = new ProcessBuilder(yourStringList);
    pb.redirectError(thisFile);
    Process p = pb.start();
    p.waitFor();
    p.destroyForcibly();
    ArrayList fileContents = getFileContents(thisFile);

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

mzsu5hc0

mzsu5hc03#

类似这样的东西也可能工作,并避免阻塞行为(而不需要创建一个文件)

InputStream error = process.getErrorStream();

// Read from InputStream
for (int k = 0; k < error.available(); ++k)
    System.out.println("Error stream = " + error.read());

从InputStream的Javadoc.可用
返回可从此输入流读取(或跳过)而不会被此输入流的方法的下一次调用阻塞的字节数的估计值。下一次调用可能是同一线程或另一个线程。单个读取或跳过此字节数不会阻塞,但可能读取或跳过较少的字节。

nsc4cvqm

nsc4cvqm4#

最简单的答案是将错误流重定向到stdout

process.getErrorStream().transferTo(System.out);

相关问题