java - 为什么在从文件重定向输入时出现异常,但 Java 程序的手动输入却没有?

标签 java windows exception

这是我的输入文件(称为 input.txt)的内容

C:\DIRECTORY_REMOVED>type input.txt
180
3
640 480
120 300
180 180

这是我运行它的 Java 程序(一个 friend 写的),

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.in 包装的 BufferedReader 一次只读取一行以填充内部缓冲区。

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

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

这意味着当您将 Scanner 包裹在 System.in 中时,它所看到的只是一个已经在 EOF 的流,它无法从中读取任何内容。

要么将 Scanner 包裹在您的 stdin 变量中,要么从一开始就使用它而不是 BufferedReader

关于java - 为什么在从文件重定向输入时出现异常,但 Java 程序的手动输入却没有?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27254889/

相关文章:

java - 如何在 Java 中逐步解码大型多字节字符串文件?

java - 运行 Spring WebApp 时代码状态 406

java - Eclipse 中未收到 "Add unimplemented methods"错误

python - 有没有一种很好的方法来处理 Python 中的异常?

java - Android:查询数据库时未捕获处理程序异常

ruby-on-rails - 如何挽救 `constantize`方法引发的错误异常?

java - Tomcat 无法在主机上下文 server.xml 中设置 'source' 属性集

windows - 如何检测是否安装了 Windows Installer?

c# - 在 C# 中创建类对象

.net - 为什么 System.Windows.MessageBoxImage 有相同值的枚举子项?