在阅读之前清除/清除System.in(stdin)

时间:2013-08-16 12:50:08

标签: java linux stdin keyboard-events

在工作中,我们在运行Linux的PC上连接了5个RFID阅读器。读者都被认为是键盘,并将他们的输入(他们从芯片中读取的内容)作为键输入事件序列发送。为了能够告诉哪个读者发送了什么序列,我正在对/dev/input/XX进行原始读取并以这种方式获取他们的输入。

这个问题是,RFID阅读器生成的发送键盘事件仍然是“in”stdin,当我尝试通过System.inScanner读取时(输入应该由这次是普通键盘),我首先从读者那里得到“待定”输入(由10个十六进制数字和一个换行符(\n)组成)。

现在,问题是:如何从stdin 中清除所有这些“待处理”输入,然后从键盘上读取我真正想要的内容?

我试过了:

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

但是stdin不允许搜索(skip抛出IOException)。

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

但是available()估计得不够(之后仍然是stdin中的东西)。

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

但是hasNextLine()永远不会变成false(打印永远不会执行)。

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

与上述相同。

任何有更多想法的人?

7 个答案:

答案 0 :(得分:3)

根据 @Joni 的建议,我把它放在一起:

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...
    }
}

这将丢弃stdin中已“挂起”的数据,并等待直到输入有效数据。在此上下文中,有效,表示十进制整数。

答案 1 :(得分:3)

这对我有用

System.in.read(new byte[System.in.available()])

答案 2 :(得分:1)

没有内置的可移植方式来刷新输入流中的数据。如果您知道待处理数据以\n结尾,为什么在您找到之前不阅读?

答案 3 :(得分:0)

设备通常使用定义良好的协议发送数据,您可以使用该协议来解析数据段。

如果我是对的,请丢弃未正确格式化协议的数据。这允许您过滤掉您不感兴趣的数据。

由于我不熟悉您使用的RFID扫描仪,我无法提供更多帮助,但这是我的建议。

答案 4 :(得分:0)

您可以使用多个线程执行此操作。

  1. 您的真实应用程序从连接到PipedOutputStream的PipedInputStream读取
  2. 您需要连续从System.in读取一个帖子。只要真正的应用程序对来自System.in的数据不感兴趣(由布尔标志指示),该线程就会丢弃它读取的所有内容。但是当真正的应用程序设置标志以指示它对来自System.in的数据感兴趣时,该线程会将它读取的所有数据发送到PipedOutputStream。
  3. 您的真实应用程序会打开标志以指示它对数据感兴趣,并在数据不再对数据感兴趣时清除该标志。
  4. 这样,来自System.in的数据总是自动刷新/清除

答案 5 :(得分:0)

相关的一个。

我读了一个double,然后需要读一个字符串。

以下工作正常:

double d = scanner.nextDouble();
scanner.nextLine(); // consumes \n after the above number(int,double,etc.)
String s = scanner.nextLine();

答案 6 :(得分:0)

处理 终端 (又称为控制台)时的最佳实践(我发现)是使用i / oa进行 交易一次 。因此,理想的做法是 以字符串形式 获取整个用户输入行,然后 根据需要将其解析 。其他任何东西不仅是特定于实现的,而且还容易阻塞。

Scanner sc = new Scanner(System.in);
String line = "";

while (true) {
    System.out.println("Enter something...");

    try {
        line = sc.nextLine();
        //Parse `line` string as you see fit here...
        break;
    } catch (Exception e) {}
}

我加入了whiletry/catch块,以便提示将在无效输入时无限循环。