这是我的输入文件的内容(称为input.txt(
C:DIRECTORY_REMOVED>type input.txt
180
3
640 480
120 300
180 180
这是我运行它的Java程序(一个朋友写的(,
import java.io.*;
import java.util.*;
class Square
{
public static void main (String args[]) throws IOException
{
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
String s;
s = stdin.readLine();
int L = Integer.parseInt(s);
String m;
m = stdin.readLine();
int N = Integer.parseInt(m);
int a = 1;
while (a <= N)
{
Scanner sc = new Scanner(System.in);
int W = sc.nextInt();
int H = sc.nextInt();
if ( W < L || H < L)
{
System.out.println("UPLOAD ANOTHER");
}
else if ( W >= L && H >= L && W == H)
{
System.out.println("ACCEPTED");
}
else
{
System.out.println("CROP IT");
}
a++;
}
}
}
编译后,如果我在命令行上手动输入输入,程序运行没有问题(见下文(,
C:DIRECTORY_REMOVED>java Square
180
3
640 480
CROP IT
120 300
UPLOAD ANOTHER
180 180
ACCEPTED
但是,如果我尝试从早期的文本文件重定向输入,则会引发异常,
C:DIRECTORY_REMOVED>java Square < input.txt
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at Square.main(Square.java:18)
如果将源代码重写为使用扫描仪而不是 BufferedReader 作为初始输入行,则异常将消失。我不明白的是为什么?
有没有人很好地解释为什么如果从命令提示符手动输入数据,代码运行良好,但如果从文件重定向则失败?
在 Windows 7(64 位(和 Windows 8.1(64 位(上观察到相同的行为。使用的JDK也是64位(Java版本8(。
题外话:该程序是为了回答HackerEarth上的一个练习谜题而编写的 - http://www.hackerearth.com/problem/algorithm/roy-and-profile-picture/
标准控制台流是行缓冲的。这意味着一旦读取了一行,读取某些数据的系统调用将返回,即使有更多输入可用。这意味着您环绕System.in
BufferedReader
一次只读取一行以填充内部缓冲区。
然后,当您将Scanner
包裹在System.in
上时,它可以从BufferedReader
停止的地方继续。
文件流是块缓冲的。如果文件足够大,系统调用将填充整个提供的缓冲区。由于文件很小,这意味着BufferedReader
将一次性读取整个文件,然后从其内部缓冲区提供数据,而基础流位于 EOF。
这意味着当你将Scanner
包裹在 System.in
上时,它看到的只是一个已经在 EOF 上的流,它无法从中读取任何内容。
要么将Scanner
包裹在stdin
变量周围,要么从头开始使用它而不是BufferedReader
。