【问题标题】:Print output and an error message to the console将输出和错误消息打印到控制台
【发布时间】:2019-01-08 05:56:15
【问题描述】:

我正在尝试将输出和错误消息打印到控制台。 但有时输出的顺序会发生变化,首先它会打印错误消息然后打印简单的消息有人能帮我理解为什么会这样吗?输出顺序大部分时间都在变化。打印输出没有一致性。我正在使用eclipse IDE,得到的输出如下。

我已尝试打印以下代码,

System.out.println("simple message");  
System.err.println("error message");  

预期的结果是这样的:

简单的消息

错误信息

但实际结果是这样的:

错误信息

简单的消息

【问题讨论】:

标签: java eclipse


【解决方案1】:

System.out.println() 和 System.err.println() 是不同的执行流。输出流被缓存,因此所有写入都进入此内存缓冲区。经过一段时间的沉寂后,它们实际上被写出来了。这是一个 for 循环,它基本上再次显示了您的错误:

for(int x = 0; x <= 5; x++) {
    System.out.println("Out");
    System.err.println("Err");



}

为了每次通过循环“刷新” Streams 调用 .flush():

for(int x = 0; x <= 5; x++) {
    System.out.println("Out");
    System.out.flush();
    System.err.println("Err");
    System.err.flush();


}

在这个 for 循环中,out 消息和 err 消息将最初打印,但在每次刷新时,您的 out 消息将首先打印,然后是您的 err 消息。输出将是这样的:

OutErr
Out
Out
Out
Out
Out

Err
Err
Err
Err
Err

那是因为 System.out 和 System.err 在不同的 Streams 上执行。

【讨论】:

    【解决方案2】:

    即使您在写入后刷新流,这些流也会由 Eclipse 中的不同线程读取,如果写入几乎同时进行,即使相应的写入到 stdout 线程也会发生读取 stderr 的线程在执行 stdout 线程之前标准输出首先发生。

    从 Java 1.5 开始就有了 ProcessBuilder 类,因此它可以在 Eclipse 中通过在启动期间将 stderr 重定向到 stdout 来解决 - 但是 Eclipse 以不同颜色显示 stderr 输出的功能会因此而被破坏。

    您可以将您的意见添加到https://bugs.eclipse.org/bugs/show_bug.cgi?id=32205

    【讨论】:

      【解决方案3】:

      由于它们是两个不同的执行流,它们独立执行。而且它们不在不同的块范围内,因此不调用 close() 导致也不调用 flush() 。然后他们处于同一水平。所以JVM在这里带头,按照他想要的方式执行这两个流。

      因此,在每个流结束时有意调用 flush() 将帮助您回到代码的主导地位

      【讨论】:

      • 我尝试在每条语句之后调用 flush(),但仍然得到相同的输出,这不是所需的输出。
      【解决方案4】:

      试试这个..

      System.out.println("Out");
      
       System.out.flush();
      
       System.err.flush();
      
       System.err.println(" err ");
      

      【讨论】:

      • 不,没用,错误信息是先打印出来的。
      【解决方案5】:

      正如之前的answers 所建议的,您可以使用System.setErr 为输出和错误流设置相同的流

      System.setErr(System.out);
      

      重新分配“标准”错误输出流。

      但不建议将此设置用于生产环境中的实际应用

      【讨论】:

        【解决方案6】:
        • 请记住,这不仅取决于用户定义的序列,还取决于接收应用程序。
        • 例如,如果 Eclipse IDE 有两个线程,一个用于接收错误流,一个用于接收 system.out 流,那么这些线程不在您的控制范围内,因此您可能会看到序列不时发生变化。
        • 如果您不关心性能,那么您可以在两者之间稍作休息。

        System.out.println("Out");

        Thread.sleep(50);

        System.err.println("error");

        【讨论】:

          【解决方案7】:

          正如 Simeon Ikudabo 所说,任务是不可能的!但对于最接近的尝试这个

          static void print(PrintStream p, Object o) throws InterruptedException {
              Object lock = new Object();
              synchronized (lock) {
          
                  Runnable r = new Runnable() {
                      public void run() {
                          synchronized (lock)
                          {
                          p.println(o);
                          lock.notify();
                          }
                      }
                  };
                  new Thread(r).start();
          
                  lock.wait();
              }
          
          }
          
          public static void main(String[] args) throws InterruptedException {
          
              for (int i = 0; i < 50; i++) {
                  print(System.out, "out");
                  print(System.err, "err");
          
              }}
          

          你可能认为它是完美的,但它仍然是一个很小的退出比赛的机会,而且也没有被授予。

          【讨论】:

            猜你喜欢
            • 2021-06-05
            • 1970-01-01
            • 2021-12-13
            • 2011-10-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多