【问题标题】:Reading streams from java Runtime.exec从 java Runtime.exec 读取流
【发布时间】:2011-03-21 13:27:24
【问题描述】:

我有以下sn-p的代码:

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

gobblers 是Runnables,它使用BufferedReader 来读取执行进程的输入和错误流。虽然这在大多数情况下都有效,但偶尔会出现一个窗口(大约 2 分钟左右),我将 processExitCode 设为 0,这表示正常终止,但输入和错误流中没有任何内容 - 甚至没有任何指示流结束。

就像我之前指出的那样,这在大多数情况下都有效,但这种故障偶尔会发生 - 我完全感到困惑。有什么想法吗?

破布

【问题讨论】:

  • 更多上下文 - 这是一个多线程应用程序,其中许多 Runtime.exec() 同时发生。抹布
  • 你的意思是流食者永远阻塞?
  • 是的!他们只是挂...

标签: java inputstream runtime.exec


【解决方案1】:

我也遇到过同样的问题。 我不记得到底出了什么问题(也许我忘了正确刷新/关闭流或其他什么......)。 无论如何,这就是我想出的。

/**
 *  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

我希望这会有所帮助。

【讨论】:

  • 我已经在做这一切,但仍然看到很多这样的问题。经过大量的试验和错误,我想我终于弄明白了:线程池的线程用完了(即使它不应该有),而读取流的线程实际上从未启动过。我将把这个问题带到 Spring 论坛! (我正在使用他们的线程池实现)感谢您的输入!
猜你喜欢
  • 2015-09-24
  • 2011-05-29
  • 1970-01-01
  • 2012-02-26
  • 2015-08-03
  • 2012-05-16
  • 2012-03-28
  • 2013-09-29
  • 1970-01-01
相关资源
最近更新 更多