如何让java程序同时打印out.println()和err.println()语句?

LGA*_*GAP 12 java

我编写了下面的java代码,它执行另一个名为"Newsworthy_RB"的java程序.

Newsworthy_RB.java包含System.out.printlln()和System.err.println()语句.

我希望在命令提示符控制台中打印输出.

为了获得相同的东西,必须做些什么.

下面的程序只打印out.println()语句而不是err.println()语句.

请告诉我下面的代码是否会像我期望的那样发挥作用?

command = "java -cp .:../sqljdbc.jar SetHash Newsworthy_RB";
Process child1 = Runtime.getRuntime().exec(command);
InputStream in1 = child1.getErrorStream();
InputStream in2 = child2.getInputStream();
while ((c = in1.read()) != -1 || (c = in2.read()) != -1) {
        System.out.print((char)c);
    }
Run Code Online (Sandbox Code Playgroud)

aio*_*obe 16

首先,启动外部程序的首选方法是通过ProcessBuilder.它甚至在文档中Runtime提到:

ProcessBuilder.start()现在是使用已修改环境启动进程的首选方法.

ProcessBuilder你有一个非常方便的方法叫redirectErrorStream:

设置此进程生成器的redirectErrorStream属性.

如果此属性为true,则此对象的start()方法随后启动的子进程生成的任何错误输出将与标准输出合并,以便可以使用Process.getInputStream()方法读取这两者.这使得更容易将错误消息与相应的输出相关联.初始值为false.

如何输出标准错误和标准输出的完整示例:

import java.io.*;

public class Test {
    public static void main(String... args) throws IOException {

        ProcessBuilder pb =
                new ProcessBuilder("java", "-cp", "yourClassPath", "HelloWorld");

        pb.redirectErrorStream(true);
        Process proc = pb.start();

        Reader reader = new InputStreamReader(proc.getInputStream());
        int ch;
        while ((ch = reader.read()) != -1)
            System.out.print((char) ch);
        reader.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

对您的更新的响应:不,代码

while ((c = in1.read()) != -1 || (c = in2.read()) != -1)
Run Code Online (Sandbox Code Playgroud)

将无法工作,因为read()是一个阻止方法,你只有一个线程.您唯一的选择是每个输入流使用一个线程,或者(最好)将两个输入流合并为一个,使用ProcessBuilder.redirectErrorStream.


Tho*_*ler 10

您需要在单独的线程中管道两个流的输出.从示例代码在这里:

Process p = Runtime.getRuntime().exec(cmd.array());
copyInThread(p.getInputStream(), System.out);
copyInThread(p.getErrorStream(), System.err);
p.waitFor();
return p.exitValue();

private void copyInThread(final InputStream in, final OutputStream out) {
    new Thread() {
        public void run() {
            try {
                while (true) {
                    int x = in.read();
                    if (x < 0) {
                        return;
                    }
                    if (out != null) {
                        out.write(x);
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    } .start();
}
Run Code Online (Sandbox Code Playgroud)

  • 来自`Runtime`的文档:"ProcessBuilder.start()现在是使用修改后的环境启动进程的首选方法." 我建议使用`ProcessBuilder.redirectErrorStream`.(见我的回答.) (3认同)