2012-03-09 73 views
2

我正在嘗試讀取我的Java程序中的stdin。我期待一連串的數字,然後換行,如:readline()在Java中返回null

6 
9 
1 

當提供通過Eclipse內置控制檯,一切順利的輸入。但是,使用Windows命令行程序打印時:

Received '6'. 
Received 'null'. 
Invalid input. Terminating. (This line is written by another function that does an Integer.parseint()). 

我的代碼是:

static String readLineFromStdIn(){ 
try{ 
     java.io.BufferedReader stdin = new java.io.BufferedReader(new java.io.InputStreamReader(System.in)); 
     String input = new String(); 
     input = stdin.readLine(); 
     System.out.println("Received '" + input + "'"); 
     return(input); 
    }catch (java.io.IOException e) { 
     System.out.println(e); 
    } 
    return "This should not have happened"; 
} 

任何線索?

+0

我在Eclipse控制檯中輸入所有數字後輸入。在Windows中,我做「java -jar program.jar user1259401 2012-03-09 13:53:22

回答

8

你得到一個null表示相關的Reader對象達到了EOF(文件結束),換句話說,他們無法獲得更多的標準輸入。現在,你的代碼明顯的問題是:

  1. 每個方法調用readLineFromStdIn()將創建一個新的BufferedReader
  2. 每個這樣從System.in
  3. BufferedReader將「競爭」與對方相同,共享輸入,沒有這些BufferedReader對象是不斷正確關閉,所以你的程序泄漏I/O資源,每次調用readLineFromStdIn()

的解決方案是使用一個單一共享BufferedReader對象的readLineFromStdIn()每次調用。

+0

這個伎倆!非常感謝。 – user1259401 2012-03-09 13:57:39

+0

每次你打開一個'stdin',它在技術上意味着你打開一個文件流,並且你永遠不會關閉它,這會超過Java可以容納的可能數量的打開文件連接。 – 2012-03-09 13:59:34

+0

@ user268396請注意,如果此「BufferedReader」已關閉,它也會關閉System.in,這可能不合意。這可能是一種罕見的情況,您只希望裝飾者流在未被關閉的情況下進行GC'd處理。 – Dev 2012-03-09 14:01:57

2

對這個問題並非真正的新答案,但我想澄清關於爲什麼原始代碼的行爲如此的評論中的混淆(我無法評論,因爲我是新來的ST,並沒有獲得聲望點)。

空結果與垃圾收集無關。下面的程序究竟遭受即使兩個讀者仍然生活在同樣的命運,訪問對象:

BufferedReader r1 = new BufferedReader(new InputStreamReader(System.in)); 
System.out.println(r1.readLine()); 
BufferedReader r2 = new BufferedReader(new InputStreamReader(System.in)); 
System.out.println(r2.readLine()); 

這一切都歸結於BufferedReader什麼是「緩衝」的意思。這是一個包含內部緩衝的Reader。內部緩衝通常顯着地提高了底層流上操作的效率,例如,通過嘗試每次讀取一個完整的緩衝區值,而不是在這裏和那裏獲得幾個字節,而不是讓這個流死亡。

所以,當你創建讀取標準第一BufferedReader,並從中讀取線會發生什麼? BufferedReader從流中讀取緩衝區滿,檢測到行結束,返回第一行,並掛起到緩衝區的其餘部分以填充其下一個請求。這將底層流定位在第一條線的末端之外。如果你的輸入很小,它可以很容易地定位在EOF。

所以,現在你來一起創建第二個BufferedReader在同一個流上 - 這是在EOF - 並試圖獲得一條線。第二個BufferedReader嘗試從底層流讀取並檢測EOF,因此readLine返回null

相關問題