Search code examples
javalinuxstdinkeyboard-events

Flush/Clear System.in (stdin) before reading


At work, we have 5 RFID readers attached to a PC running Linux. The readers are all recognized as keyboards and send their input (what they read form the Chip) as an key-input-event sequence. To be able to tell which reader send what sequence, I'm doing a raw-read over /dev/input/XX and get their input this way.

The problem with this is, that the send keyboard-events generated by the RFID readers are still "in" stdin and when I try to read from System.in via Scanner (input should be generated by a normal keyboard this time), I first get the "pending" input from the readers (which consists of 10 Hex-decimal digits and a newline (\n)).

Now, the question is: How can I flush all these "pending" input's from stdin and then read what I really want from the keyboard?

I tried:

System.in.skip(System.in.available());

But seek is not allowed on stdin (skip throws an IOException).

for (int i = 0; i < System.in.available(); i++){
  System.in.read();
}

But available() doesn't estimate enough (still stuff in stdin afterwards).

Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()){
  scanner.nextLine();
}
System.out.println("Clean!");

But hasNextLine() never becomes false (the print never executes).

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = in.readLine()) != null);
System.out.println("Clean!");

Same as above.

Anyone with any more ideas?


Solution

  • Based on @Joni's advice, i put this together:

    Scanner scanner = new Scanner(System.in);
    int choice = 0;
    while (scanner.hasNext()){
        if (scanner.hasNextInt()){
            choice = scanner.nextInt();
            break;
        } else {
            scanner.next(); // Just discard this, not interested...
        }
    }
    

    This discards the data that is already "pending" in stdin and waits until valid data is entered. Valid, in this context, meaning a decimal integer.