0

I have two groups of data I need to take from the user of an unknown size, and I would like it if the user could specify the end of their input with Ctrl-D (Ctrl-Z in Windows I believe).

This works flawlessly for the first group, but the second group reads nothing. In fact, after EOF is sent to the console, I'm unable to read from System.in at all for the remainder of the program (readLine() will always return null).

How do I effectively "reopen" System.in in order to read more inputs after an EOF input?

Here is some example code to express what I'm trying to accomplish:

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader systemIn = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));

        String line;
        System.out.println("Enter first inputs (Ctrl-D to close)");
        while ((line = systemIn.readLine()) != null) {
            System.out.printf("Received input %s%n", line);
        }
        System.out.println("First inputs have been received!\n");

        // What do I put here to use System.in again?

        System.out.println("Enter second inputs (Ctrl-D to close)");
        while ((line = systemIn.readLine()) != null) {
            System.out.printf("Received input %s%n", line);
        }
        System.out.println("Second inputs have been received!\n");
    }
}
Software Engineer
  • 15,457
  • 7
  • 74
  • 102
Thane
  • 372
  • 4
  • 8
  • @saka1029 Unfortunately this is not my issue, because the stream isn't closed. if it was closed, the second while loop would throw `java.io.IOException: Stream closed`, which it does not. `readLine` simply always return null. – Thane Apr 14 '21 at 23:46
  • 1
    Once EOF is reached, it is not possible to reset the stream's state so that you can continue reading from it. – Jim Garrison Apr 14 '21 at 23:51
  • I'm unable to reproduce this problem on macOS and Linux with JDK 8 and 12. It reads the second input just fine after Ctrl-D. Are you sure Java's stdin is a tty? – that other guy Apr 14 '21 at 23:55
  • @JimGarrison So, it's simply impossible to do so in java? I know in C it's as simple as calling [`clearerr(stdin)`](https://stackoverflow.com/questions/51194821). That would really be unfortunate if this is just a language limitation. – Thane Apr 14 '21 at 23:55
  • @thatotherguy Thank you so much for this post! Turns out, its my IDE (both intellij and eclipse had this issue). If I ran the program just through a Linux terminal, it behaves as I expect, but whatever my IDEs are doing to wrap the standard input causes them to hold on to that EOF character forever. – Thane Apr 15 '21 at 00:13
  • IF you have a console attached to the jvm, you can use the `java.io.Console` class, where `readLine()` signals EOF by returning `null` but allows you to continue reading if more input is available. This does not work in my Eclipse (`System.console()` returns `null` meaning it doesn't think there's a console available) but it works if I run the class in the command line. – Jim Garrison Apr 15 '21 at 00:19
  • 2
    The IDE undoubtedly uses pipes to talk to the process, while this Ctrl-D behavior is specific to tty devices. I would really suggest additionally also accepting a blank line or single dot on a line by itself to end input so that the program can easily be used in other contexts like automation, inetd, or via such an IDE. – that other guy Apr 15 '21 at 00:37

0 Answers0