Java:在System.setOut之后写入真正的STDOUT

我试图拦截System.out和System.err,但保持在必要时直接写入原始流的能力。

PrintStream ps = System.out; System.setOut(new MyMagicPrintStream()); ps.println("foo"); 

不幸的是,System类实现的细节意味着在我的例子中,“foo”被发送到真正的stdout的MyMagicPrintStream instread。 有谁知道如何获得真实/原始OutputStreams的引用。

谢谢!

PS:否则会导致StackOverflowError < – 用于SEO。

尝试这个:

 PrintStream ps = new PrintStream(new FileOutputStream(FileDescriptor.out)) 

尝试这样的事情:

  PrintStream original = new PrintStream(System.out); // replace the System.out, here I redirect to NUL System.setOut(new PrintStream(new FileOutputStream("NUL:"))); System.out.println("bar"); // no output // the original stream is still available original.println("foo"); // output to stdout 
 PrintStream original = System.out; System.setOut(new MyMagicPrintStream()); // This will print to MyMagicPrintStream(); System.out.println("foo for MyMagicPrintStream"); System.setOut(original); // This will print to original print stream; System.out.println("foo for original print stream (stdout)"); 

这对我有用。

PrintStream original = new PrintStream(System.out); 基本上包装了现有的引用 – 所以如果System.setOut()正在改变它 – 应该没有区别。 这可能是特定JVM的问题,但我宁愿猜测MyMagicPrintStream或写入stdout的代码有问题。 实际上,以下代码完全符合Sun 1.6.0_20-b02 for Windows的预期:

 import java.io.FileOutputStream; import java.io.PrintStream; public class SystemOutTest { public static void main(String args[]) { try { PrintStream ps = System.out; System.setOut(new PrintStream(new FileOutputStream("stdout.log"))); System.out.println("foo"); ps.println("bar"); } catch (Exception e) { e.printStackTrace(); } } } 

“foo”转到stdout.log,“bar”转到控制台。

此外,如果您需要访问分配给JVM启动的原始stdin / out – 您可以使用System.console(); (只记得 – 它可以为null !)