【发布时间】:2023-10-28 01:12:01
【问题描述】:
当字符来自System.in 时,是否有一种优雅的方式来触发事件?我想避免轮询InputStream.available()。
【问题讨论】:
-
您应该注意 System.in 是行缓冲的,因此您不能一次读取一个按键。如果你想要一个界面应用程序,你需要一个 GUI。
标签: java events input stream stdin
当字符来自System.in 时,是否有一种优雅的方式来触发事件?我想避免轮询InputStream.available()。
【问题讨论】:
标签: java events input stream stdin
您必须创建一个单独的线程来阻止读取,直到有可用的内容。
如果你不想真正吃掉输入,你必须用一个内部缓冲区包装它,读入缓冲区,喊叫,当被要求输入时,从缓冲区返回数据。
你可以这样解决:
InputStream stdin = System.in;
// Create a wrapper (with it's own dedicated read-thread)
MyListenableInputStream listenableInputStream =
new MyListenableInputStream(stdin);
// Update System.in with something more useful.
System.setIn(listenableInputStream);
【讨论】:
当然...启动一个阻塞输入的线程,然后在它得到某些东西时调用您的事件方法。
【讨论】:
很笼统地说:
如果您已经有一个事件反应器正在运行,请创建一个线程并让它在read() 上阻塞。当有可用数据时,让该线程将事件排入队列以供反应器处理。如果你做不到,大多数事件反应器都提供了InvokeLater 或CallLater 方法,供你在事件处理线程中运行一些代码。
通知或安排函数调用后,返回阻塞read()。
【讨论】:
如果你想要一些优雅的东西,你可以轻松实现一个ObservableInputStream,它接受一个Listener,它会收到有关数据可用性的警告,但你必须使用一个定期检查数据并调用监听器的内部线程来实现它案例。
考虑一下这样一个事实,即流不应该用作发送小数据包的对象,而是发送连续的字节流,这就是为什么这种方法仅在提供给输入流的数据无效时才有效的原因过于频繁地到达(否则它会一直随意调用侦听器)。此外,您必须关心一致性,如果数据到达时某些东西已经可用并且侦听器被警告,那么某些东西可能会占用所有字节(您应该将其放在临时缓冲区中)但是如果有更多数据刚刚到达,您应该决定如何处理(与缓冲区一起提供,放入缓冲区并再次调用侦听器等)
【讨论】:
new Thread(){
public void run() {
while(System.in.get()){
}
}.start();
【讨论】: