2016-11-16 70 views
1

我正在通過Java IO。剛剛開始使用標準輸入和輸出流。請看下面給出的簡單程序,我想知道System.err是如何工作的

public static void main(String args[]){ 
     Scanner scanner = new Scanner(System.in); 
     System.out.println("Give us your input"); 
     String str = scanner.nextLine(); 

     System.out.println("Standard Output: " + str); 
     System.err.println("Standard Error Output: " +str); 
    } 

輸出會隨着運行這兩三次而變化。請找情侶低於輸出,

運行的第一次:

給我們您輸入 我的名字 標準錯誤輸出:我的名字 標準輸出:我的名字

過程完成,退出碼0

運行第二次與同一代碼: 給我們您輸入 我的名字 標準輸出:我的名字 標準E RROR輸出:我的名字

過程完成,退出代碼爲0

我想知道爲什麼用System.err的輸出變化

回答

1

的System.out和System.err寫入到通過不同的管道連接到命令外殼不同的數據流。命令外殼將從這些管道讀取數據並將其寫入您的控制檯應用程序。這將最終寫入您的屏幕。

有很多地方寫入一個數據流的數據可能會「超過」寫入另一個數據的數據。

  • 它可能發生在JVM本身,因爲Java規範不能保證先寫哪個流。 (事實上​​,如果只有一個線程正在寫程序,這是不太可能的,在目前的Java實現中,行爲可能是確定性的,雖然未指定。)

  • 它可能發生在OS中,對寫入兩個獨立管道的數據傳送順序不作任何保證。

  • 它可能發生在shell中,因爲shell規範中沒有任何內容會優先從管道讀取任何內容。

總之,有很多地方的行爲是未指定的。

還值得注意的是,觀察到的行爲可能取決於您使用的Java版本,操作系統和操作系統工具,硬件以及系統負載。

最後,您可能無法確保觀察到的交錯(或不是)一致。如果您需要一致性,請將您的輸出專門寫入一個流或另一個流。

3

你的程序將寫入第一System.out,然後System.err(和println會同時刷新這些流),但不能保證兩個流的順序/交錯將出現在控制檯中。

既然你幾乎在同一時間給他們寫信,你會得到兩種組合。我想你甚至可能會得到半線交織。

+0

我已經跑了很多次,沒有發生交錯。不知道爲什麼不。 – mdewit

+0

@mdewit:我不認爲你會真正看到交錯,除非你打開輸出流清除或手動刷新奇怪的地方(也許甚至不是)。但你*可能*。在一天結束時,控制檯將如何/何時顯示這些數據。 – Thilo

+0

如果您同時從多個線程寫入單個流(如'System.out'),您將看到交錯。 – Thilo

0

System.out, System.in, System.err沒有任何訂單的保證首先可以出現這樣這些流的順序並不固定