Eclipse 如何从以 javaw.exe 开始的进程捕获标准输出?

How does Eclipse capture stdout from a process started with javaw.exe?

假设您正在 运行Eclipse 中编写一个简单的 HelloWorld 程序。 System.out.println("Hello, World!"); 的输出在 'Console' 选项卡中清晰可见。但是,如果您随后打开 'Debug' 透视图并显示 'Process properties' window,您将看到如下内容:

Path:
C:\Program Files\Java\jdk1.8.0_144\bin\javaw.exe

Working Directory:
C:\eclipse-workspace\HelloWorld

Command Line:
"C:\Program Files\Java\jdk1.8.0_144\bin\javaw.exe" 
-Dfile.encoding=Cp1250 
-classpath "<blah-blah>" 
HelloWorld

所以,看起来它正在使用 javaw.exe 来启动 JVM。但是,如果您 运行 从命令行执行完全相同的命令,您将看不到任何输出(正如您所期望的那样,因为 javaw 应该与 stdout 和 stderr 分离)。

那么,Eclipse 如何捕获和显示该输出?我希望能够做同样的事情...

创建您自己的 PrintStream 并使用 System.setOut(PrintStream out) 方法。

public class RedirectSystemOut {
     public static void main(String[] args) throws FileNotFoundException {
         System.out.println("This goes to the console");
         PrintStream console = System.out;

         File file = new File("out.txt");
         FileOutputStream fos = new FileOutputStream(file);
         PrintStream ps = new PrintStream(fos);
         System.setOut(ps);
         System.out.println("This goes to out.txt");

         System.setOut(console);
         System.out.println("This also goes to the console");
    }
}

要在 Java 中重定向外部进程的输出流,您可以使用 ProcessBuilder class。

示例用法

public class Main {
    public static void main(String[] args) throws Exception {
        ProcessBuilder pb = new ProcessBuilder("javaw", "-version")
                .inheritIO();
        Process p = pb.start();
        int returnValue = p.waitFor();
        System.out.println(returnValue);
    }
}

示例输出

java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
0