2

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

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

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

我试过:

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

但是在标准输入上不允许搜索(skip抛出一个IOException)。

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

但是available()估计不够(之后仍然在标准输入中)。

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!");

和上面一样。

有更多想法的人吗?

4

8 回答 8

4

根据@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...
    }
}

这将丢弃标准输入中已经“待定”的数据,并等待输入有效数据。有效,在此上下文中,表示十进制整数。

于 2013-08-16T14:29:33.007 回答
3

这对我有用

System.in.read(new byte[System.in.available()])
于 2015-10-20T10:47:24.207 回答
1

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

于 2013-08-16T13:29:33.643 回答
1

一个相关的。

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

以下工作正常:

double d = scanner.nextDouble();
scanner.nextLine(); // consumes \n after the above number(int,double,etc.)
String s = scanner.nextLine();
于 2018-05-05T14:41:42.447 回答
0

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

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

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

于 2013-08-16T12:54:58.420 回答
0

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

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

这样,来自的数据System.in总是自动刷新/清除

于 2016-01-28T03:18:37.543 回答
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) {}
}

我包括while&try/catch块,以便提示将在无效输入时无限循环。

于 2019-02-21T01:52:43.377 回答
0

你可以试试:

System.in.skipNBytes(System.in.available());
于 2021-10-12T03:46:57.937 回答