从 java Runtime.exec 读取流

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3343066/
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-30 01:24:29  来源:igfitidea点击:

Reading streams from java Runtime.exec

javainputstreamruntime.exec

提问by ragstorooks

I have the following snippet of code:

我有以下代码片段:

Process proc = runtime.exec(command);
errorGobbler = new ErrorStreamGobbler(proc.getErrorStream(), logErrors, mdcMap);
outputGobbler = new OutputStreamGobbler(proc.getInputStream(), mdcMap);
executor.execute(errorGobbler);
executor.execute(outputGobbler);
processExitCode = proc.waitFor();

where the gobblers are Runnables which use a BufferedReaderto read the input and error streams of the executing process. While this works most of the time, I get the occasional window (of about 2 minutes or so) where I get the processExitCodeas 0, which indicates normal termination but there is nothing in the input and error streams - nothing to even indicate end-of-stream.

其中 gobbler 是Runnables,它使用 aBufferedReader来读取执行进程的输入和错误流。虽然这在大多数情况下都有效,但我偶尔会得到一个窗口(大约 2 分钟左右),在那里我得到processExitCode0,这表示正常终止,但输入和错误流中没有任何内容 - 甚至没有表示结束-溪流。

Like I indicated before, this works most of the time but this failure occurs every once in a while - and I am totally puzzled. Any ideas?

就像我之前指出的那样,这在大多数情况下都有效,但这种失败每隔一段时间就会发生一次 - 我完全感到困惑。有任何想法吗?

Rags

破布

回答by Raphael Jolivet

I've struggled with the same kind of issues. I can't remember what exactly was wrong (maybe I forgot to flush / close the streams correctly or something ...). Anyway, here is what I came up with.

我一直在努力解决同样的问题。我不记得到底出了什么问题(也许我忘记正确冲洗/关闭流或其他东西......)。无论如何,这就是我想出的。

/**
 *  Handle communication with a process, reading its output/error and feeding its input
 *  @param process The process to execute
 *  @param _in Reader that will feed the input pipe of the process
 *  @param out Writer that will receive the output of the process
 *  @param err Writer that will receive the error pipe of the process
 */
public static void communicate(
        Process process,
        final Reader _in,
        final Writer out,
        final Writer err)
{
    // Buffer the input reader
    final BufferedReader in = new BufferedReader(_in);

    // Final versions of the the params, to be used within the threads
    final BufferedReader stdOut = new BufferedReader(new InputStreamReader(process.getInputStream()));
    final BufferedReader stdErr = new BufferedReader(new InputStreamReader(process.getErrorStream()));
    final BufferedWriter stdIn = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));

    // Thread that reads std out and feeds the writer given in input
    new Thread() {
        @Override public void run() {
            String line;
            try {
                while ((line = stdOut.readLine()) != null) {
                   out.write(line + newline);
                }
            } catch (Exception e) {throw new Error(e);}
            try {
                out.flush();
                out.close();
            } catch (IOException e) { /* Who cares ?*/ }
        }
    }.start(); // Starts now

    // Thread that reads std err and feeds the writer given in input
    new Thread() {
        @Override public void run() {
            String line;
            try {
                while ((line = stdErr.readLine()) != null) {
                    err.write(line + newline);
                }
            } catch (Exception e) {throw new Error(e);}
            try {
                err.flush();
                err.close();
            } catch (IOException e) { /* Who cares ?*/ }
        }
    }.start(); // Starts now

    // Thread that reads the std in given in input and that feeds the input of the process
    new Thread() {
        @Override public void run() {
            String line;
            try {
                while ((line = in.readLine()) != null) {
                    stdIn.write(line + newline);
                }
            } catch (Exception e) {throw new Error(e);}

            try {
                stdIn.flush();
                stdIn.close();
            } catch (IOException e) { /* Who cares ?*/ }
        }
    }.start(); // Starts now

    // Wait until the end of the process
    try {
         process.waitFor();
    } catch (Exception e) {
        throw new Error(e);
    }

} // End of #communicate

I hope this helps.

我希望这有帮助。