2017-06-07 29 views
1

從的PrintStream documentation立即看到System.out.print輸出到控制檯。因此PrintStream在每次打印後都會刷新,不僅是println?

可選地,可以創建一個PrintStream以便自動沖洗; 這意味着一個字節 陣列被寫入後,的其中一個println方法調用換行符 字符或字節(「\ n」)被寫入flush方法自動調用

然後給出代碼

System.out.print("hi"); // gives console output: hi 
System.out.print(7);  // gives console output: 7 

// prevents flushing when stream wiil be closed at app shutdown 
for (;;) { 
} 

爲什麼然後我看到輸出到我的控制檯?控制檯(來自System.out的PrintStream實例),什麼都不應寫入,因爲到目前爲止沒有任何內容會被刷新!

This沒有回答這個問題。我猜,答案是在源代碼(私人實用工具方法BufferedWriter.flushBuffer()),但我不明白註釋代碼:「刷新輸出緩衝區到基礎字符流,而不會沖洗流本身「:如果PrintStream(與控制檯輸出關聯),即」流本身「不刷新,則不會刷新輸出到控制檯!...

PrintStream.print(String) :

private void write(String s) { 
     try { 
      synchronized (this) { 
       ensureOpen(); 
       textOut.write(s); 
       textOut.flushBuffer(); 
       charOut.flushBuffer(); 
       if (autoFlush && (s.indexOf('\n') >= 0)) 
        out.flush(); 
      } 
     } 
     catch (InterruptedIOException x) { 
      Thread.currentThread().interrupt(); 
     } 
     catch (IOException x) { 
      trouble = true; 
     } 
    } 

BufferedWriter.flushBuffer()的源代碼:

/** 
    * Flushes the output buffer to the underlying character stream, without 
    * flushing the stream itself. This method is non-private only so that it 
    * may be invoked by PrintStream. 
    */ 
    void flushBuffer() throws IOException { 
     synchronized (lock) { 
      ensureOpen(); 
      if (nextChar == 0) 
       return; 
      out.write(cb, 0, nextChar); 
      nextChar = 0; 
     } 
    } 

更多細節也給出here。這是非常複雜的,但似乎在某個階段BufferedWriter被賦予給PrintStream構造函數。

回答

0

我使用調試器一步一步走到,這是我發現: enter image description here String s顯示在第527行之後的主機,所以它的前行528,其中具有\n的檢查完成。

charOut.flushBuffer()內心深處,有一個叫下面的方法:enter image description here

其中,檢查有關\n丟失。

流動是因爲它遵循:

  1. System.out#print(String s)電話PrintStream#print(String s)
  2. PrintStream#print(String s)來電PrintStream#write(String s)
  3. PrintStream#write(String s)來電OutputSteamWriter#flushBuffer()
  4. OutputStreamWriter#flushBuffer()來電StreamEncoder#flushBuffer()
  5. StreamEncoder#flushBuffer()來電StreamEncoder#implFlushBuffer()
  6. StreamEncoder#implFlushBuffer()來電StreamEncoder#writeBytes()
  7. StreamEncoder#writeBytes()來電PrintStream#write(byte buf[], int off, int len)這沖刷了buffor if(autoFlush)

以上是最重要的片段。在此流程中似乎不會調用BufferedWriter

+0

這正是OP所問的 - 在這種情況下爲什麼會影響事物? –

+0

API說,如果自動刷新設置爲true,那麼只有println被刷新,而不是打印(!!!)。我在PrintStream(它的第一段)中引用了apidoc:「或者,可以創建PrintStream以便自動刷新;這意味着在寫入字節數組後,會自動調用flush方法,調用其中一個println方法,或者一個換行符或字節('\ n')被寫入。「 – LrnBoy

+0

我也猜測它的自動沖洗設置爲true,但任何人都可以指向它發生的地方嗎?我目前找不到這個地方... – LrnBoy