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?
You could do this with multiple threads.
System.in
continuously. As long as the real application is not interested in the data coming from System.in (indicated by a boolean flag), this thread discards everything that it reads. But when the real application sets the flag to indicate that it is interested in the data coming from System.in, then this thread sends all the data that it reads to the PipedOutputStream.This way, the data from
System.in
is always automatically flushed/cleadThis worked for me
Devices usually send data using a well defined protocol which you can use to parse data segments.
If I'm right, discard data that isn't properly formatted for the protocol. This allows you to filter out the data you aren't interested in.
As I'm not familiar with the RFID scanner you're using I can't be of more help, but this is what I suggest.
A related one.
I read a double, then needed to read a string.
Below worked correctly:
Based on @Joni's advice, i put this together:
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.
There is no built-in portable way to flush the data in an input stream. If you know that the pending data ends with
\n
why don't you read until you find it?