java 从进程中读取错误流

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12908732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 10:44:39  来源:igfitidea点击:

Reading error stream from a process

javaprocessiostreamjava-io

提问by user496934

I am writing a java program to read the error stream from a process . Below is the structure of my code --

我正在编写一个 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);
    }

The above code works fine if anything is actually written to the error stream of the invoked process. However, if anything is not written to the error stream, then the call to readLine actually hangs indefinitely. 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.

如果实际上有任何内容写入被调用进程的错误流,则上述代码工作正常。但是,如果没有将任何内容写入错误流,则对 readLine 的调用实际上会无限期挂起。但是,我想让我的代码通用,以便它适用于所有场景。如何修改我的代码以实现相同的目标。

Regards, Dev

问候,开发

采纳答案by sarysa

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

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

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.

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

回答by Brian Roach

readline()is a blocking call. 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).

readline()是阻塞调用。它将阻塞,直到有一行要读取(由行尾字符终止)或底层流关闭(返回 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? 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.

编辑添加:话虽如此,它不应该“无限期地”按原样挂起;一旦被调用的进程终止,它应该返回。无论如何,您调用的进程是否也在向 输出某些内容stdout?如果是这种情况……您也需要从中读取数据,否则缓冲区将填满并阻止外部进程,这将阻止它退出……从而导致您的问题。