簡體   English   中英

readline()在Java中返回null

[英]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(文件末尾),換句話說,他們無法獲得更多的標准輸入。 現在,代碼的明顯問題是:

  1. 每次調用readLineFromStdIn()都會創建一個新的 BufferedReader
  2. 對於來自System.in的相同的共享輸入,每個這樣的BufferedReader將彼此“競爭”
  3. 並且這些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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM