简体   繁体   中英

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

Here are the contents of my input file (called input.txt)

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

And here is the Java program I'm running it against (a friend wrote it),

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++;
        }
    }

}

After compiling, if I were to manually enter the input on the command line, the program runs without issues (see below),

C:\DIRECTORY_REMOVED>java Square
180
3
640 480
CROP IT
120 300
UPLOAD ANOTHER
180 180
ACCEPTED

But if I attempt to redirect the input from the earlier text file an exception gets thrown,

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)

If the source code is re-written to use Scanner instead of BufferedReader for the initial input lines, the exception goes away. What I don't understand is WHY?

Does anyone have a good explanation of why the code runs perfectly fine if the data is entered manually from command prompt, but fails if redirected from a file?

The same behavior has been observed on Windows 7 (64-bit) and Windows 8.1 (64-bit). JDK used is also 64-bit (Java version 8).

OFF-TOPIC: The program was written in answer to a practice puzzle on HackerEarth - http://www.hackerearth.com/problem/algorithm/roy-and-profile-picture/

The standard console stream is line-buffered . That means that a system call to read some data will return once one line has been read, even if more input is available. This means that the BufferedReader you wrap around System.in just reads one line at a time to fill the internal buffer.

Then, when you wrap the Scanner around System.in , it can continue from where the BufferedReader left off.

File streams are block-buffered . A system call will fill the entire supplied buffer if the file is large enough. Since your file is small, this means that the BufferedReader will read the entire file in one go, and then supply data from its internal buffer, while the underlying stream sits at EOF.

This means that when you wrap the Scanner around System.in , all it sees is a stream already at EOF, from which it can't read anything.

Either wrap the Scanner around your stdin variable or use it from the beginning instead of the BufferedReader .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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