2010-07-29 73 views
1

我有以下片段調用一個寫入STDERR和STDOUT的perl腳本。 我一直在遵循建議的過程,例如自動刷新perl腳本中的STDOUT和STDERR並使用streamgobbler線程。我注意到這可以幫助我的問題達到某種程度,但有時候perl腳本會產生大量輸出,但仍然會填滿它的管道並掛起。唯一似乎停止這添加到我的Perl腳本以下顯然我想輸出,所以這不是一個選項。java似乎並沒有讀取我的perl管道輸出,並正在填滿

更新>>

另一個有趣的發生難度時,我貓在/ proc/PID/FD /管#在linux下它會導致讀取管道進行訪問。這似乎轉儲管道的內容意味着我的Perl進程可以再次寫入它,從而完成。因此,我的java進程不能正確讀取進程輸出流。

PERL:

close STDOUT 
close STDERR 

我的Java看起來像下面

parserProcess = run.exec(config.getCMDArray(),env); 

StreamGobbler errorGobbler = new StreamGobbler(parserProcess.getErrorStream(), "ERROR"); 

    // any output? 
    StreamGobbler outputGobbler = new StreamGobbler(parserProcess.getInputStream(), "OUTPUT"); 

    // kick them off 
    errorGobbler.start(); 
    outputGobbler.start(); 

因此StreamGobbler是 - >

class StreamGobbler extends Thread 
{ 
    InputStream is; 
    String type; 

StreamGobbler(InputStream is, String type) 
{ 
    this.is = is; 
    this.type = type; 
} 

public void run() 
{ 
    try 
    { 
     InputStreamReader isr = new InputStreamReader(is); 
     BufferedReader br = new BufferedReader(isr); 
     String line=null; 
     while ((line = br.readLine()) != null) 
      System.out.println(type + ">" + line);  
     } catch (IOException ioe) 
      { 
      ioe.printStackTrace(); 
      } 
} 
} 



String line=""; 

status = parserProcess.waitFor(); 

在此先感謝

+0

如果你所有的Perl腳本都關閉了STDOUT和STDERR,難怪你明白了;)你能發佈你的Perl腳本嗎? – mfontani 2010-07-29 11:50:58

回答

2

我覺得你描述n你的perl和java應用程序的正式行爲。管道後面的緩衝區的實際大小不確定/取決於操作系統,但可能只有1KB或16KB。輸出產生過程阻塞直到其文本被消耗爲止是明智的;什麼是替代方案?爲管道緩衝區分配更大量的內存?

如果您使用上述代碼進行實驗,那麼您的處理速度會受到Java控制檯輸出(即System.out.println()調用)的瓶頸。我認爲,如果你評論打印出來(僅用於測試),你會看到Java唾手可得的Perl輸出。

+0

另一種方法是通過文件進行你的進程間通信。這樣做的好處是不會阻塞你的輸出(或者至少在磁盤滿了之前),儘管它也有缺點(需要清除輸入流上的EOF條件,性能,磁盤填滿的東西,......) – mob 2010-07-29 14:41:02

+1

那麼,他可以讓Perl程序寫入文件並運行完成,然後啓動Java應用程序並運行它...我們不知道是否有嚴格的要求,兩個程序並行運行。但基於文件修補管道似乎是一個可怕的想法。 – 2010-07-29 14:50:28

相關問題