2010-11-23 146 views
2

当字符可从System.in获得字符时,是否有优雅的方式来触发事件?我想避免投票InputStream.available()如何异步读取stdin?

+0

您应该注意System.in是行缓冲的,因此您一次无法读取一个按键。如果你想要一个接口应用程序,你需要一个GUI。 – 2010-11-23 22:37:22

回答

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

强大的答案,谢谢。 – 2011-04-30 04:29:56

2

当然......开始一个阻塞输入的线程,然后在事件方法被调用时调用你的事件方法。

0
new Thread(){ 

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

}.start(); 
0

非常一般地讲:

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

通知或调度函数调用后,返回到read()上的阻塞。

0

如果你想要的东西优雅,你可以很容易地实现一个ObservableInputStream它接受被警告数据的可用性Listener但你必须有内螺纹定期检查数据来实现它,并呼吁听众的情况。

想想一个事实,即流不应该被用作发送小的数据包,但连续的字节流对象,这就是为什么如果是考虑到输入流中的数据没有这种做法只会工作有效地到达太频繁(否则它会继续呼叫收听者随意)。另外,如果有数据到达时,如果有数据到达,并且监听器被警告,则可能需要所有字节(应该放在临时缓冲区中),但是如果有更多数据刚刚到达,您应该决定如何处理(将它与缓冲区放在一起,放入缓冲区并再次呼叫监听器等)