为了调试需要,需要把Java输出的信息重定向到文件进行保留,同时为了方便,在Console上的输出也得保留。
原理很简单,就是自定义输出流,并使用System.setOut
和System.setErr
进行设置。在自定义的输出流中把输出的信息顺手保存到文件上一下。
自定义一个用于分发的输出流:
DistributOutputStream.java
Java
public class DistributOutputStream extends OutputStream { private OutputStream[] outputStreams = null; public DistributOutputStream(OutputStream[] outputStreams) { super(); this.outputStreams = outputStreams; } @Override public void write(int v) throws IOException { for (OutputStream os : outputStreams) { try { os.write(v); } catch (IOException e) { } } } @Override public void close() throws IOException { for (OutputStream os : outputStreams) { try { os.close(); } catch (IOException e) { } } } @Override public void flush() throws IOException { for (OutputStream os : outputStreams) { try { os.flush(); } catch (IOException e) { } } } }
自定义输出流中只是重写了write、flush和close方法,为了提高效率可以继续重写其他几个写多字节的write方法。所有这些方法都是对需要分发的输出流进行的操作,用了try,但为了避免循环调用catch之后没在打印信息了。
使用起来也很简单:
Java
try { // 创建一个文件流 FileOutputStream fos = new FileOutputStream("console.log"); // 先保存原来的标准输出 OutputStream cos = System.out; // 创建一个分发流分发到文件流和标准输出 DistributOutputStream osc = new DistributOutputStream(new OutputStream[] { fos, cos }); // 分发流的打印方式 PrintStream ps = new PrintStream(osc); // 设置到Err和Out System.setErr(ps); System.setOut(ps); } catch (Exception e) { e.printStackTrace(); return; } // 不出意外的话Console和文件里面都有Hello World~了 System.out.println("Hello World~");
打好收工~