InheritIO 和重定向标准输出
InheritIO and redirecting stdout
我正在尝试为使用 ProcessBuilder.inheritIO 的 class 编写测试,但我似乎无法让它工作。我已经将代码剥离到核心并提出了以下示例,我认为应该将子进程的所有输出写入 ByteArrayOutputStream 但没有。
环境:Java9.0.4 Windows7
import java.io.*;
public class ProcessTest {
public static void main(String[] args) throws Throwable {
PrintStream original = System.out;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
System.setOut(ps);
System.out.println("BEGIN");
Process process = new ProcessBuilder().command("where", "where")
.inheritIO().start();
process.waitFor();
System.out.println("END");
String output = new String(baos.toByteArray());
original.println("output = " + output);
}
}
输出为:
C:\Windows\System32\where.exe
output = BEGIN
END
而且当我查看调试器时,输出流不包含指向 where 的路径。
我认为 System.setOut 没有按我的想法行事,但我不确定。我发现其他 SO 问题建议使用 StreamGrabber,但我认为这是针对 Java 6 及更早版本的,并且 inheritIO 对我有用。任何帮助,将不胜感激。谢谢。
编辑
我开始意识到调用 System.setOut()
并不是我所希望的那样。它不会更改 1
的基础文件描述符。如果我在 C 中这样做,我将使用低级文件描述符。但这不是 setOut()
所做的。那只是改变指针。
System.setOut 更改 Java 进程的标准输出。不能保证它会影响子进程。
无论如何,仅仅为了捕获单个进程的输出而更改全局设置可能不是一个好主意,特别是如果您希望您的代码 运行 在其他代码(库、应用程序等)中.).
解决方案:不要尝试破解 System.out。从进程的标准输出 InputStream 中读取:
ProcessBuilder builder = new ProcessBuilder().command("where", "where").inheritIO();
builder.redirectOutput(ProcessBuilder.Redirect.PIPE);
Process process = builder.start();
String output;
try (InputStream processStdOut = process.getInputStream()) {
output = new String(processStdOut.readAllBytes());
}
process.waitFor();
我正在尝试为使用 ProcessBuilder.inheritIO 的 class 编写测试,但我似乎无法让它工作。我已经将代码剥离到核心并提出了以下示例,我认为应该将子进程的所有输出写入 ByteArrayOutputStream 但没有。
环境:Java9.0.4 Windows7
import java.io.*;
public class ProcessTest {
public static void main(String[] args) throws Throwable {
PrintStream original = System.out;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
System.setOut(ps);
System.out.println("BEGIN");
Process process = new ProcessBuilder().command("where", "where")
.inheritIO().start();
process.waitFor();
System.out.println("END");
String output = new String(baos.toByteArray());
original.println("output = " + output);
}
}
输出为:
C:\Windows\System32\where.exe
output = BEGIN
END
而且当我查看调试器时,输出流不包含指向 where 的路径。
我认为 System.setOut 没有按我的想法行事,但我不确定。我发现其他 SO 问题建议使用 StreamGrabber,但我认为这是针对 Java 6 及更早版本的,并且 inheritIO 对我有用。任何帮助,将不胜感激。谢谢。
编辑
我开始意识到调用 System.setOut()
并不是我所希望的那样。它不会更改 1
的基础文件描述符。如果我在 C 中这样做,我将使用低级文件描述符。但这不是 setOut()
所做的。那只是改变指针。
System.setOut 更改 Java 进程的标准输出。不能保证它会影响子进程。
无论如何,仅仅为了捕获单个进程的输出而更改全局设置可能不是一个好主意,特别是如果您希望您的代码 运行 在其他代码(库、应用程序等)中.).
解决方案:不要尝试破解 System.out。从进程的标准输出 InputStream 中读取:
ProcessBuilder builder = new ProcessBuilder().command("where", "where").inheritIO();
builder.redirectOutput(ProcessBuilder.Redirect.PIPE);
Process process = builder.start();
String output;
try (InputStream processStdOut = process.getInputStream()) {
output = new String(processStdOut.readAllBytes());
}
process.waitFor();