2010-11-23 333 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但你必須有內螺紋定期檢查數據來實現它,並呼籲聽衆的情況。

想想一個事實,即流不應該被用作發送小的數據包,但連續的字節流對象,這就是爲什麼如果是考慮到輸入流中的數據沒有這種做法只會工作有效地到達太頻繁(否則它會繼續呼叫收聽者隨意)。另外,如果有數據到達時,如果有數據到達,並且監聽器被警告,則可能需要所有字節(應該放在臨時緩衝區中),但是如果有更多數據剛剛到達,您應該決定如何處理(將它與緩衝區放在一起,放入緩衝區並再次呼叫監聽器等)