2012-03-09 180 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

相关问题