如何异步读取标准输入?

时间:2010-11-23 21:07:26

标签: java events input stream stdin

System.in提供字符时,是否有一种优雅的方式可以触发事件?我想避免轮询InputStream.available()

5 个答案:

答案 0 :(得分:3)

你必须创建一个单独的线程,阻止读取,直到某些东西可用。

如果你不想实际吃掉输入,你必须用内部缓冲区包装它,读入缓冲区,喊出来,当被要求输入时,从缓冲区中返回数据。

你可以这样解决:

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

答案 1 :(得分:2)

当然......启动一个阻塞输入的线程,然后在它获取某些东西时调用你的事件方法。

答案 2 :(得分:0)

new Thread(){

   public void run() {
      while(System.in.get()){
   }

}.start();

答案 3 :(得分:0)

非常一般地说:

如果您已经有一个事件反应器正在运行,请创建一个线程并让它在read()上阻止。当有可用数据时,让该线程将一个事件排入队列以供反应堆处理。如果您不能这样做,大多数事件反应器都会提供InvokeLaterCallLater方法,以便您在事件处理线程中运行一些代码。

通知或安排函数调用后,请返回read()上的阻止。

答案 4 :(得分:0)

如果你想要一些优雅的东西,你可以很容易地实现一个ObservableInputStream接受一个Listener,它会收到关于数据可用性的警告,但是你必须用一个定期检查数据的内部线程来实现它。打电话给听众。

考虑一下这样一个事实:流不应该被用作发送小数据包但是连续字节流的对象,这就是为什么这种方法只有在输入流的数据没有有效的情况下才能工作的原因过于频繁地到达(否则它将继续随意调用听众)。此外,你必须关心一致性,如果数据在某些东西已经可用时到达并且监听器被警告,那么某些东西可以占用所有字节(你应该放在一个临时缓冲区中)但是如果有更多的数据刚到,你应该决定如何处理(将缓冲区放在一起,放在缓冲区中,再次调用监听器等)