繁体   English   中英

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

[英]Why am I getting an exception when redirecting input from file, but not manual input for a Java program?

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

如果将源代码重写为在初始输入行中使用Scanner而不是BufferedReader,则该异常消失。 我不明白为什么?

如果有人从命令提示符手动输入数据,但是从文件重定向失败,为什么有人能很好地解释为什么代码运行得很好呢?

在Windows 7(64位)和Windows 8.1(64位)上已经观察到相同的行为。 使用的JDK也是64位(Java版本8)。

主题外:该程序是为回答HackerEarth上的一个实践难题而编写的-http: //www.hackerearth.com/problem/algorithm/roy-and-profile-picture/

标准控制台流是行缓冲的 这意味着读取一行数据的系统调用将在读取一行后返回,即使有更多输入可用。 这意味着环绕System.inBufferedReader一次只能读取一行以填充内部缓冲区。

然后,将Scanner包裹在System.in周围时,它可以从BufferedReader停止的地方继续。

文件流是块缓冲的 如果文件足够大,系统调用将填充整个提供的缓冲区。 由于您的文件很小,因此这意味着BufferedReader将一次性读取整个文件,然后从其内部缓冲区提供数据,而基础流位于EOF。

这意味着,当您将Scanner包裹在System.in周围时,它所看到的只是EOF处的流,它无法读取任何内容。

Scanner包裹在您的stdin变量周围,或者从头开始使用它而不是BufferedReader

暂无
暂无

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

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