简体   繁体   English

readline()在Java中返回null

[英]readline() returns null in Java

I'm trying to read the stdin in my Java program. 我正在尝试在我的Java程序中读取stdin。 I'm expecting a series of numbers followed by newlines, like: 我期待一系列数字后跟换行符,例如:

6  
9  
1  

When providing the input through the eclipse built-in console, everything goes well. 通过eclipse内置控制台提供输入时,一切顺利。 But when using the Windows command line, the program prints: 但是当使用Windows命令行时,程序会打印:

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

My code is: 我的代码是:

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";  
}  

Any clues? 有线索吗?

That you get a null indicates that the relevant Reader objects reached an EOF (end of file), or in other words that they can't get any more standard input. 得到null表示相关的Reader对象到达了EOF(文件末尾),换句话说,他们无法获得更多的标准输入。 Now the obvious issues with your code are: 现在,代码的明显问题是:

  1. Each method call to readLineFromStdIn() will create a new BufferedReader . 每次调用readLineFromStdIn()都会创建一个新的 BufferedReader
  2. Each such BufferedReader will be “competing” with each other for the same, shared input from System.in 对于来自System.in的相同的共享输入,每个这样的BufferedReader将彼此“竞争”
  3. And none of these BufferedReader objects are ever properly closed, so your program leaks I/O resources with each call to readLineFromStdIn() . 并且这些BufferedReader对象都没有被正确关闭,因此每次调用readLineFromStdIn() ,程序都会泄漏I / O资源。

The solution is to use a single shared BufferedReader object for each invocation of readLineFromStdIn() . 解决方案是为readLineFromStdIn()每次调用使用单个共享BufferedReader对象。

Not really a new answer to this question, but I wanted to clear up confusion in the comments about why the original code behaved as it did (I can't comment because I'm new to ST and haven't garnered reputation points). 这个问题并不是一个新的答案,但是我想在评论中澄清原始代码为何如此表现的混淆(我不能发表评论,因为我是ST的新手而没有获得声望点)。

The null result has nothing to do with garbage collection. null结果与垃圾收集无关。 The following program suffers exactly the same fate even though both readers still live, accessible objects: 即使两个读者仍然活着,可访问的对象,下面的程序也会遭遇完全相同的命运:

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());

It all comes down to what "Buffered" means in BufferedReader . 这一切都归结于什么是“缓冲”指BufferedReader It's a Reader that includes internal buffering. 它是一个包含内部缓冲的Reader The internal buffering usually significantly improves the efficiency of operations on the underlying stream, eg by attempting to read a full buffer's worth each time, rather than nickle-and-diming the stream to death getting a few bytes here and a few there. 内部缓冲通常可以显着提高底层流上的操作效率,例如,通过尝试每次读取一个完整的缓冲区值,而不是将流扼杀到流中,在这里获得几个字节和一些字节。

So what happens when you create the first BufferedReader on stdin and read a line from it? 那么当您在stdin上创建第一个BufferedReader并从中读取一行时会发生什么? That BufferedReader reads a buffer-full from the stream, detects the end of line, returns the first line, and hangs on to the rest of the buffer to fill its next request. BufferedReader从流中读取缓冲区已满,检测到行尾,返回第一行,并挂起到缓冲区的其余部分以填充其下一个请求。 That leaves the underlying stream positioned beyond the end of that first line. 这使得底层流位于第一行的末尾之外。 And if your input is small, it could easily be positioned at EOF. 如果您的输入很小,它可以很容易地定位在EOF。

So now you come along and create a second BufferedReader atop the same stream - which is at EOF - and attempt to get a line. 所以现在你来到同一个流的顶部创建第二个BufferedReader - 这是在EOF - 并尝试获得一条线。 The second BufferedReader attempts to read from the underlying stream and detects EOF, so readLine returns null . 第二个BufferedReader尝试从底层流中读取并检测EOF,因此readLine返回null

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM