How to make Redirect.INHERIT and System.setOut work together

ぐ巨炮叔叔 提交于 2020-02-04 01:29:29

问题


This may be a trivial question but I can't easily find an answer. I've got a simple program in Java:

System.setOut(new PrintStream(new File("stdout.txt")));
...
...
ProcessBuilder pb = new ProcessBuilder("... some args ...");
pb.inheritIO();
pb.start().waitFor();

My intention is to store all output of the process (including child pb) in the stdout.txt. But, this seem not to work and the output of pb is redirected to my process parent's standard output as if System.setOut(...) was never called.

Is there any way I can use pb.inheritIO/pb.inheritOutput methods to redirect to a redirected System.out? Am I missing something obvious? I know I can do it the old way by reading from the child's standard output manually in a thread but that's just more hassle.

Cheers, Jacek


回答1:


Please see my answer https://stackoverflow.com/a/32342557/5226711:

The I/O redirection of ProcessBuilder does not redirect streams but file descriptors. Even setting System.out to another stream does not change the file descriptor of the initial standard output. ProcessBuilder.inheritIO() inherits the parent process' standard output/input/error file descriptors.

The PrintStream instance is not passed to the started operating system process, but rather something like (it is pseudo code, I do not think it actually works):

((FileOutputStream) System.out.out).getFD()

Or, more correct:

FileDescriptor.out

which is static final indicating that it will not change, even if you set System.out to something different.

Regarding your question, this means you have to use a File and ProcessBuilder.redirectOutput(File) instead of a PrintStream:

ProcessBuilder pb = new ProcessBuilder("... some args ...");
pb.redirectOutput(new File("stdout.txt"));
pb.start().waitFor();

This redirects only the output of the child process to stdout.txt.

If you want to direct all output from both the parent and the child process, you have to redirect the parent's System.out to the file and capture the child's output in the parent and output it to its redirected System.out:

System.setOut(new PrintStream(new File("stdout.txt")));
ProcessBuilder pb = new ProcessBuilder("... some args ...");
Process p = pb.start();
BufferedReader childOutput = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = output.readLine()) != null) {
    System.out.println(line); // child`s output goes to stdout.txt
}


来源:https://stackoverflow.com/questions/23131139/how-to-make-redirect-inherit-and-system-setout-work-together

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!