简体   繁体   English

System.out和System.err调用的随机打印顺序

[英]Random printing order for System.out & System.err calls

Please see the code snippet below 请参阅下面的代码段

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadFile {


    public static void main(String[] args)  {

        String str="";
        FileReader fileReader=null;

        try{


            // I am running on windows only  & hence the path :) 
            File file=new File("D:\\Users\\jenco\\Desktop\\readme.txt");
            fileReader=new FileReader(file);
            BufferedReader bufferedReader=new BufferedReader(fileReader);
            while((str=bufferedReader.readLine())!=null){
                System.err.println(str);
            }

        }catch(Exception exception){
            System.err.println("Error occured while reading the file : " + exception.getMessage());
            exception.printStackTrace();
        }
        finally {
            if (fileReader != null) {
                try {
                    fileReader.close();
                    System.out.println("Finally is executed.File stream is closed.");
                } catch (IOException ioException) {

                    ioException.printStackTrace();
                }
            }
        }

    }

}

When I execute the code multiple times , I get output randomly as below , sometimes the System.out statement gets printed first in the console , sometimes the System.err gets printed first. 当我多次执行代码时,我会随机输出如下所示,有时System.out语句首先在控制台中打印,有时会先打印System.err。 below are the random outputs that I get 下面是我得到的随机输出

Output 1 输出1

Finally is executed.File stream is closed.
this is a text file 
and a java program will read this file.

Output 2 输出2

this is a text file 
and a java program will read this file.
Finally is executed.File stream is closed.

Why is this so ? 为什么会这样?

I believe this is because you are writing to two different outputs (one is standard out and the other standard error). 我相信这是因为你正在写两个不同的输出(一个是标准输出,另一个是标准错误)。 These are probably handled by two different threads at runtime to allow writing to both during java execution. 这些可能在运行时由两个不同的线程处理,以允许在Java执行期间写入两者。 Assuming this is the case, the cpu task scheduler is not going to execute the threads in the same order every time. 假设是这种情况,cpu任务调度程序不会每次都以相同的顺序执行线程。

You should never get this functionality if all of your output is going to the same output stream (ie everything goes to standard out or everything goes to standard err). 如果所有输出都转到相同的输出流(即所有输出都标准输出或一切都符合标准错误),则永远不应该获得此功能。 You will never be guaranteed execution order of standard error vs standard output. 永远不会保证标准错误与标准输出的执行顺序。

Because System.out and System.err are both pointing to the console in your case. 因为System.out和System.err都指向您的控制台。

To demonstrate, if you add System.out.flush() and System.err.flush() after println(), then the output will be consistant. 为了演示,如果在println()之后添加System.out.flush()和System.err.flush(),那么输出将是一致的。

This has already been answered here: 这已在这里得到解答:

Java: System.out.println and System.err.println out of order Java:System.out.println和System.err.println乱序

This happens because your finally clause is using System.out and the other code is using System.err. 发生这种情况是因为您的finally子句正在使用System.out而其他代码正在使用System.err。 The err stream is flushing out prior to the out stream or vice versa. 错误的流在流出之前刷新,反之亦然。

As a result, the order of printed data will not be guaranteed to come out in the same order that it is called. 因此,打印数据的顺序将不会保证与调用的顺序相同。

You can always have your console direct the err stream to a file or the out stream to a file for later inspection. 您始终可以让控制台将错误的流指向文件,或将流指向文件以供以后检查。 Or, change your code to print everything to System.out. 或者,更改代码以将所有内容打印到System.out。 Many programmers do not use err and the usefulness is debatable unless you capture err separate from the console. 许多程序员不使用err,除非你从控制台中分离出错误,否则它的用处是有争议的。

Just use out! 用完了!

Over and out... 完了,走吧...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM