首页 > 解决方案 > “将 STDOUT 复制到文件而不停止它在屏幕上显示”中的示例不起作用

问题描述

使用“将 STDOUT 复制到文件而不停止在屏幕上显示”中的示例,Tee 操作后的输出未按预期工作。

从 stackOverflow 上的示例中学习和复制代码。

public class TeeStreams extends PrintStream {
    public static void main(String[] args) throws FileNotFoundException {
        System.out.println("test sysout before");
        System.err.println("test syserr before");

        PrintStream orgSO = System.out;
        PrintStream orgSE = System.err;

        PrintStream logout = new PrintStream(new FileOutputStream("D:\\TeeStreams.log", false));

        PrintStream teeStdOut = new TeeStreams(System.out, logout);
        PrintStream teeStdErr = new TeeStreams(System.err, logout);

        System.setOut(teeStdOut);
        System.setErr(teeStdErr);

        System.out.println("test sysout inside"); //error here...both copies are in log, no console display
        System.err.println("test syserr inside"); //error here...both copies are in log, no console display

        System.setOut(orgSO);
        System.setErr(orgSE);

        teeStdOut.close();
        teeStdErr.close();

        System.out.println("test sysout after");
        System.err.println("test syserr after");
    }    

    public TeeStreams(PrintStream out1, PrintStream out2) {
        super(out1);
        this.out = out2;
    }

    public void write(byte buf[], int off, int len) {
        try {
            super.write(buf, off, len);
            out.write(buf, off, len);
        } catch (IOException ex) {
        }
    }

    public void close() {
        //super.close();  // causes NullPointerException
        try {
            out.close();
        } catch (IOException ex) {
        }
    }
}

奇怪的是,输出到日志的格式出乎意料:

test sysout insidetest sysout inside

test syserr insidetest syserr inside

Tee 处于活动状态时没有输出到控制台....两个副本都进入日志文件。日志文件格式异常。为什么日志文件不包含 4 行而不是 2 行(实际上是 2 个文本和 2 个空白)?之前和之后的显示按预期工作。

我在 NetBeans 中运行它……与 NB 处理控制台的方式有冲突吗?

标签: java

解决方案


在网上找到了另一个解决此问题的示例。用这些行替换上述相关代码;

    private PrintStream ps1, ps2;
    public TeeStreams(PrintStream out1, PrintStream out2) {
        super(out1);
        this.out = out2;
        ps1 = out1;
        ps2 = out2;
    }

    @Override
    public void write(byte buf[], int off, int len) {
        ps1.write(buf, off, len);
        ps2.write(buf, off, len);
    }

推荐阅读