2013-08-28 28 views
4

爪哇:爲什麼從過程讀取的InputStream塊altough數據可用

Process p = Runtime.getRuntime().exec("myCommand"); 
final InputStream in = p.getInputStream(); 

new Thread() 
{ 
    public void run() 
    { 
     int b; 
     while ((b = in.read()) != -1) // Blocks here until process terminates, why? 
      System.out.print((char) b); 
    } 
}.start(); 

CPP:

#include <stdio.h> 
#include <unistd.h> 

int main(int argc, char** argv) 
{ 
    printf("round 1\n"); 

    // At this point I'd expect the Java process be able 
    // to read from the input stream. 

    sleep(1); 

    printf("round 2\n"); 

    sleep(1); 

    printf("round 3\n"); 

    sleep(1); 

    printf("finished!\n"); 

    return 0; 

    // Only now InputStream.read() stops blocking and starts reading. 
} 

InputStream.read()的文檔狀態:

這方法阻塞,直到輸入數據可用,流的末尾被檢測到,或拋出異常。

是的,我知道這(因而與Linux有關?):

java.lang.Process中:因爲有些本機平臺僅針對標準輸入和輸出提供有限的緩衝區大小流,沒有及時寫入輸入流或讀取子流程的輸出流可能導致子流程阻塞甚至死鎖。

我的問題是:

  1. 爲什麼InputStream.read()阻塞雖然我應該已經有數據可右側的過程開始之後?我在任何一方遺漏了什麼?

  2. 如果它與linux相關,有沒有什麼辦法可以從進程的輸出流中讀取而不會阻塞?

+8

嘗試在每個printf()後添加一個fflush(stdout)。 –

+0

其實這工作!謝謝。此外,我找到了更通用的解決方案:setbuf(stdout,NULL),http://stackoverflow.com/questions/1716296/why-does-printf-not-flush-after-the-call-unless-a-換行符是在格式嚴格 – bcause

+1

Upvoted毫無意義的無法解釋的downvote – EJP

回答

6

爲什麼從過程讀取的InputStream塊雖然數據是可用的

它沒有。這裏的問題是數據不是當你認爲它是可用的,這是由發件人的緩衝引起的。

可以克服與fflush()按@ MarkkuK。的評論,或者告訴stdio沒有緩衝stdout可言,按照你的。

+0

謝謝你,總結! – bcause

0

還有一個我發佈的解決方案here,其中包括在使用InputStream#available()之前從Process流中讀取任何內容。

相關問題