System.out 和 System.err 的区别

System.out 和 System.err 的区别, 很基础吧,

但是 仔细观察idea 的后台日志, 你会有新的发现。

测试一段极其简单的代码:

public class TestBasic {
 
    public static void main(String[] args) {
        System.out.println("test System.out = " + 111);
        System.err.println("test System.err = " + 222);
        System.out.println("test System.out = " + 111);
        System.err.println("test System.err = " + 222);
        System.out.println("test System.out = " + 111);
        System.err.println("test System.err = " + 222);
    }

}

结果:

第一个问题:为什么System.out 和 System.err 的打印结果有不同的颜色

估计是idea 的控制台的默认的 人性化的设置 —— 使用cmd 命令行, 肯定的、自然不会有红色。 linux shell 呢? 

第二个问题: 为什么是先白后红, 而不是红白相间的呢? 跟我的程序的操作的顺序不一样啊! why ?!

不够快吗? 线程切换吗? 打印更多试试:

public class TestBasic {
 
    public static void main(String[] args) {
        System.out.println("test System.out = " + 111);
        System.err.println("test System.err = " + 222);
        System.out.println("test System.out = " + 111);
        System.err.println("test System.err = " + 222);
        System.out.println("test System.out = " + 111);
        System.err.println("test System.err = " + 222);

        for (int i = 0; i < 1000; i++) {
            System.out.println("test System.out = " + i);
            System.err.println("test System.err = " + i);
        }
    }

}

还是一样的的, 显示白色的System.out, 再是红色的 System.err :

可以看到, 对于 test System.err = xx 打印, xx 都是递增的, 单独是有序的,但是System.out 、 System.err整体就不是了!

把 1000 改成2000, 看到了不同的结果, 看来是 println 方法有缓存, 观察源码发现,这个缓存是 java io底层实现的sun  io 的缓存。

当print 流缓存未满的时候, println不会立即输出, 而是等待 一个flush 强制输出或者 缓存满, 那么 缓存大小 默认是多少呢? 默认是 8kb。因为 底层都是 BufferedWriter

另外,测试发现,

第一批 是先打印  System.out 还是 System.err , 和 第一行有关, 上面的测试代码, 如果把第一行和第二行调换一下, 那么 打印的结果是 先红后白了!

本质上还是同步的, 没有异步的问题。 之前 一直在想, 是不是 异步线程导致了这个问题?

另外, 

java.lang.Throwable#printStackTrace()  其实是使用的是 System.err :

    public void printStackTrace() {
        printStackTrace(System.err);
    }

    /**
     * Prints this throwable and its backtrace to the specified print stream.
     *
     * @param s {@code PrintStream} to use for output
     */
    public void printStackTrace(PrintStream s) {
        printStackTrace(new WrappedPrintStream(s));
    }

    private void printStackTrace(PrintStreamOrWriter s) {
        // Guard against malicious overrides of Throwable.equals by
        // using a Set with identity equality semantics.
        Set<Throwable> dejaVu =
            Collections.newSetFromMap(new IdentityHashMap<Throwable, Boolean>());
        dejaVu.add(this);

        synchronized (s.lock()) {

    ...

当然, 我们可以改变, 比如:

throwables.printStackTrace(System.out);

PrintWriter write 没有输出,(8192 没有输出, 8193 才有输出)

        char[] array = new char[8192];// 8192 没有输出, 8193 才有输出
        Arrays.fill(array,'s');
        PrintWriter pw= new PrintWriter(System.out);
        pw.write(array);// 8192 没有输出, 8193 才有输出

但是呢, 似乎也不能累加,第一次如果设置 数组小于 8193, 后面再write 也没有用!

        char[] array = new char[8192];
        Arrays.fill(array,'s');
        PrintWriter pw= new PrintWriter(System.out);
        pw.write(array);// 8192 没有输出, 8193 才有输出

        char[] array2 = new char[7190];
        Arrays.fill(array2,'c');
        pw.write(array2);

这样才可以():

char[] array = new char[8192];
        Arrays.fill(array,'s');
        PrintWriter pw= new PrintWriter(System.out);
        pw.write(array);// 8192 没有输出, 8193 才有输出

        char[] array2 = new char[7190];
        Arrays.fill(array2,'c');
        pw.write(array2);

        array2 = new char[1];
        Arrays.fill(array2,'c');
        pw.write(array2);

        array2 = new char[1000];
        Arrays.fill(array2,'c');
        pw.write(array2);

        array2 = new char[3];
        Arrays.fill(array2,'c');
        pw.write(array2);

此时要大于 两个 8192 才可以! 至于为什么,我也没有深究。 感觉怪怪的。

另外就是发现,flush 方法的话,会及时刷出,不会有不输出的问题。PrintWriter(OutputStream out, boolean autoFlush) 的autoFlush参数, 也无助于上面的问题,而是仅仅对  println, printf, or format 方法起作用; 它会在执行 println, printf, or format 方法的时候,会 flush the output buffer。


版权声明
本文原创发表于 博客园,作者为 阿K .     本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
欢迎关注本人微信公众号:觉醒的码农,或者扫码进群:

原文地址:https://www.cnblogs.com/FlyAway2013/p/15200869.html