为什么在从文件重定向输入时出现异常,而不是 Java 程序的手动输入



这是我的输入文件的内容(称为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

相关内容

最新更新