ProcessBuilder.inheritIO()将输出发送到错误的地方

时间:2014-05-20 07:22:16

标签: java redirect java-7 processbuilder system.out

我正在使用inheritIO()将我的计划中子进程的输出重定向到System.outSystem.err,并输入到System.in

这些都被System.setOut()等重定向:

// Reassign System IO
System.setIn(cpanel.getConsole().getInputStream());
System.setOut(new PrintStream(cpanel.getConsole().getOutputStream()));
System.setErr(new PrintStream(cpanel.getConsole().getOutputStream()));

但是当我运行这个过程时:

String[] fullargs = new String[sargs.length+4];
fullargs[0] = "java";
fullargs[1] = "-classpath";   // Runtime classpath option.
fullargs[2] = cpath;          // Specify the classpath.
fullargs[3] = mname;          // Specify class to run.

for(int i=0; i<sargs.length; i++)
{
    fullargs[i+4] = sargs[i]; // Put together arguments.
}

ProcessBuilder proc = new ProcessBuilder()
                            .inheritIO()
                            .command(fullargs);


try
{
    System.out.println("RUNNING...");
    proc.start();
}
catch(IOException ioe)
{
    JOptionPane.showMessageDialog(null,
        "There was a system error invoking this program.",
        "ERROR",
        JOptionPane.ERROR_MESSAGE);
}

重定向到曾经 System.out等,而不是重定向到的内容。

如果我注释掉inheritIO()行,则输出会丢失,并且不会出现在任何地方。使用inheritIO(),它将转到父进程的标准控制台,而不是重定向的控制台。我打印的行&#34; RUNNING&#34;转到正确的重定向位置。换句话说,如果我没有重定向父进程的输出流,inheritIO()正在完成应该做的事情。它将转到父进程的旧控制台。

我不知道为什么会这样,我把头发拉到这里。我已经看到inheritIO()在Windows中不起作用,但在Mac OS和Linux上这个问题是相同的。我使用的是Java 7。

1 个答案:

答案 0 :(得分:0)

请在此处注明我的回答:https://stackoverflow.com/a/32350856/5226711

应用于您的问题,这意味着您可以使用https://stackoverflow.com/a/14165567/5226711中提议的StreamGobbler的改编版本:

private class StreamGobbler extends Thread {
    private InputStream in;
    private PrintStream out;

    private StreamGobbler(InputStream in, PrintStream out) {
        this.in = in;
        this.out = out;
    }

    @Override
    public void run() {
        try {
            BufferedReader input = new BufferedReader(new InputStreamReader(in));
            String line = null;
            while ((line = input.readLine()) != null)
                out.println(line);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

并像这样使用它:

String[] fullargs = new String[sargs.length+4];
fullargs[0] = "java";
fullargs[1] = "-classpath";   // Runtime classpath option.
fullargs[2] = cpath;          // Specify the classpath.
fullargs[3] = mname;          // Specify class to run.

for(int i=0; i<sargs.length; i++)
{
    fullargs[i+4] = sargs[i]; // Put together arguments.
}

ProcessBuilder pb = new ProcessBuilder().command(fullargs);

try
{
    System.out.println("RUNNING...");
    Process p = pb.start();
    StreamGobbler pOut = new StreamGobbler(p.getInputStream(), new PrintStream(cpanel.getConsole().getOutputStream()));
    StreamGobbler pErr = new StreamGobbler(p.getErrorStream(), new PrintStream(cpanel.getConsole().getOutputStream()));
    pOut.start();
    pErr.start();
}
catch(IOException ioe)
{
    JOptionPane.showMessageDialog(null,
        "There was a system error invoking this program.",
        "ERROR",
        JOptionPane.ERROR_MESSAGE);
}

重定向子项的stdin不包含在我的示例中。