2011-08-23 133 views
43

爲什麼某些流需要被刷新(FileOutputStream和套接字流),而標準輸出流不?當/爲什麼叫System.out.flush()在Java中

每當有人使用System.outPrintStream對象,無論是在調用println()write(),他們從來不沖洗流。但是,其他程序員習慣於與其他流一起呼叫flush() a PrintStream/PrintWriter

我最近問這個問題給幾個程序員,有些人認爲在Java中有一些後臺處理來自動刷新System.out流,但我找不到任何文檔。

像這樣的事情使我懷疑,如果簡單地調用System.out.println()是獨立於平臺的一些系統可能需要在沖洗流。

回答

43

System.out是基於它默認刷新每當一個新行寫入一個PrintStream左右。

javadoc

自動沖洗 - 一個布爾值;如果是真的,每當一個字節數組寫入輸出緩衝器會被刷新,的println方法調用其中一個或一個換行符或字節('\n')寫

所以你提到的println情況下被顯式處理,並且與byte[]的情況也保證進行刷新,因爲它落在「每當寫入一個字節數組」時。

如果您使用System.setOut替換System.out並且不使用自動填充流,那麼您將不得不像其他任何流一樣使用自動填充流。

庫代碼可能不應該直接使用System.out,但是如果是這樣,那麼它應該小心刷新,因爲庫用戶可能會覆蓋System.out以使用非刷新流。

任何將二進制輸出寫入System.out的Java程序在exit之前應該小心flush,因爲二進制輸出通常不包含尾隨換行符。

+3

唯一有效的'如果真',但果真如此嗎?我找不到任何關於自動刷新的對的System.out ... –

+1

@Carlos價值的任何文件,它是由該引導了JVM並啓動主類什麼'System.out'和'System.err'是系統必然會發生什麼以及如何沖洗。當您使用'java'二進制推出的一類'System.out'被初始化爲像'新的PrintStream(新FileOutputStream中(FileDescriptor.out),真實,System.getProperty(「file.encoding的」))'但其他JVM不同。顯然,嵌入小應用程序的JVM會有所不同。 –

+0

@MikeSamuel,那麼這是否意味着我們仍然需要* *由於自動沖洗行爲不** **保證在規格反正刷新? – Pacerier

2

System.out默認是行緩衝的。所以,如果你打電話println而不是print它不應該是一個問題。有關更多信息,請參閱this article

+1

對不起,println不必用於爲PrintStream獲取自動刷新。請確認。 –

5

PrintStream documentation

任選地,PrintStream可以創建以便自動沖洗;這意味着一個字節數組被寫入後的flush方法自動調用,的println方法之一被調用時,或者一個新行字符或字節('\n')被寫入。

雖然我沒有看到它在文檔中明確提到,但我的理解是System.out將執行此自動刷新。

3

當你不能等到要顯示的項目,沖洗流。

當JVM出現故障,無法刷新流風險在顯示緩衝區丟失的物品,這可能使有意義的錯誤信息,告訴你爲什麼JVM下去永遠失去了。這使得調試變得更加困難,因爲人們往往會說,「但它沒有到達,因爲它會打印出來」。