[英]readline() returns null in Java
我正在嘗試在我的Java程序中讀取stdin。 我期待一系列數字后跟換行符,例如:
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";
}
有線索嗎?
得到null
表示相關的Reader
對象到達了EOF(文件末尾),換句話說,他們無法獲得更多的標准輸入。 現在,代碼的明顯問題是:
readLineFromStdIn()
都會創建一個新的 BufferedReader
。 System.in
的相同的共享輸入,每個這樣的BufferedReader
將彼此“競爭” BufferedReader
對象都沒有被正確關閉,因此每次調用readLineFromStdIn()
,程序都會泄漏I / O資源。 解決方案是為readLineFromStdIn()
每次調用使用單個共享BufferedReader
對象。
這個問題並不是一個新的答案,但是我想在評論中澄清原始代碼為何如此表現的混淆(我不能發表評論,因為我是ST的新手而沒有獲得聲望點)。
null結果與垃圾收集無關。 即使兩個讀者仍然活着,可訪問的對象,下面的程序也會遭遇完全相同的命運:
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
。 內部緩沖通常可以顯着提高底層流上的操作效率,例如,通過嘗試每次讀取一個完整的緩沖區值,而不是將流扼殺到流中,在這里獲得幾個字節和一些字節。
那么當您在stdin上創建第一個BufferedReader
並從中讀取一行時會發生什么? BufferedReader
從流中讀取緩沖區已滿,檢測到行尾,返回第一行,並掛起到緩沖區的其余部分以填充其下一個請求。 這使得底層流位於第一行的末尾之外。 如果您的輸入很小,它可以很容易地定位在EOF。
所以現在你來到同一個流的頂部創建第二個BufferedReader - 這是在EOF - 並嘗試獲得一條線。 第二個BufferedReader嘗試從底層流中讀取並檢測EOF,因此readLine
返回null
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.