简体   繁体   English

从进程读取错误 stream

[英]Reading error stream from a process

I am writing a java program to read the error stream from a process.我正在编写一个 java 程序来从进程中读取错误 stream。 Below is the structure of my code --以下是我的代码结构——

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);
    }

The above code works fine if anything is actually written to the error stream of the invoked process.如果实际上向调用进程的错误 stream 写入了任何内容,则上述代码可以正常工作。 However, if anything is not written to the error stream, then the call to readLine actually hangs indefinitely.但是,如果没有向错误 stream 写入任何内容,那么对 readLine 的调用实际上会无限期挂起。 However, I want to make my code generic so that it works for all scenarios.但是,我想让我的代码通用,以便它适用于所有场景。 How can I modify my code to achieve the same.我怎样才能修改我的代码来实现相同的目的。

Regards, Dev问候,开发

readline() is a blocking call. readline()是一个阻塞调用。 It will block until there's a line to be read (terminated by an end of line character) or the underlying stream is closed (returning EOF). 它将阻塞,直到有一行要读取(由行尾字符终止)或底层流关闭(返回EOF)。

You need to have logic that is checking BufferedReader.ready() or just using BufferedReader.read() and bailing out if you decide you're waiting long enough (or want to do something else then check again). 您需要具有检查BufferedReader.ready()或仅使用BufferedReader.read()逻辑,并且如果您决定等待足够长时间(或者想要执行其他操作然后再次检查),则需要挽救。

Edit to add : That being said, it shouldn't hang "indefinitely" as-is; 编辑添加 :话虽如此,它不应该“无限期”挂起; it should return once the invoked process terminates. 一旦被调用的进程终止,它就应该返回。 By any chance is your invoked process also outputting something to stdout ? 你调用的进程有没有输出到stdout东西? If that's the case ... you need to be reading from that as well or the buffer will fill and will block the external process which will prevent it from exiting which ... leads to your problem. 如果是这种情况......你也需要从中读取或缓冲区将填充并阻止外部进程,这将阻止它退出...导致你的问题。

This is a late reply, but the issue hasn't really solved and it's on the first page for some searches. 这是一个迟到的回复,但问题并没有真正解决,它在一些搜索的第一页。 I had the same issue, and BufferedReader.ready() would still set up a situation where it would lock. 我有同样的问题, BufferedReader.ready()仍会设置一个锁定的情况。

The following workaround will not work if you need to get a persistent stream. 如果需要获取持久流,则以下解决方法将不起作用。 However, if you're just running a program and waiting for it to close, this should be fine. 但是,如果你只是运行一个程序并等待它关闭,这应该没问题。

The workaround I'm using is to call ProcessBuilder.redirectError(File) . 我正在使用的解决方法是调用ProcessBuilder.redirectError(File) Then I'd read the file and use that to present the error stream to the user. 然后我会读取该文件并使用它向用户显示错误流。 It worked fine, didn't lock. 它工作正常,没有锁定。 I did call Process.destroyForcibly() after Process.waitFor() but this is likely unnecessary. 我在Process.destroyForcibly()之后调用了Process.destroyForcibly() ,但这可能是不必要的。

Some pseudocode below: 下面有一些伪代码:

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);

I hope this helps with at least some of your use cases. 我希望这对至少一些用例有帮助。

Something like this might also work and avoid the blocking behaviour (without requiring to create a File)这样的事情也可能有效并避免阻塞行为(无需创建文件)

InputStream error = process.getErrorStream();

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

From the Javadoc of InputStream.available来自 InputStream.available 的 Javadoc

Returns an estimate of the number of bytes that can be read (orskipped over) from this input stream without blocking by the nextinvocation of a method for this input stream.返回可以从此输入 stream 读取(或跳过)的字节数的估计值,而不会被下一次调用此输入 stream 的方法阻塞。 The next invocationmight be the same thread or another thread.下一次调用可能是同一个线程或另一个线程。 A single read or skip of thismany bytes will not block, but may read or skip fewer bytes.单次读取或跳过这么多字节不会阻塞,但可能会读取或跳过更少的字节。

The simplest answer would be to simply redirect the error stream to stdout :最简单的答案是简单地将错误 stream 重定向到stdout

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM