繁体   English   中英

读取前刷新/清除 System.in (stdin)

[英]Flush/Clear System.in (stdin) before reading

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

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

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

我试过了:

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

同上。

有人有更多想法吗?

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

这将丢弃标准输入中已经“挂起”的数据,并等待直到输入有效数据为止。 在这种情况下有效,表示十进制整数。

这对我有用

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

没有内置的便携式方法可以刷新输入流中的数据。 如果您知道待处理的数据以\\n结尾,那么为什么不查找直到找到呢?

一个相关的。

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

下面正常工作:

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

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

如果我是对的,请丢弃协议格式不正确的数据。 这使您可以过滤出您不感兴趣的数据。

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

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

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

这样, System.in的数据将始终自动刷新/清除

处理终端设备 (又称控制台)时(我发现)的最佳做法是一次处理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块,以便提示将在无效输入时无限循环。

你可以试试:

System.in.skipNBytes(System.in.available());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM