2009-06-22 23 views
0

在Java 1.6中使用ProcessBuilder是否存在線程安全的方式來並行地使用來自外部進程的標準輸出?從外部進程併發地使用標準輸出

背景:我需要調用pbzip2將大文件解壓縮到標準輸出,並在文件解壓縮時處理每一行(pbzip2利用多個CPU,與其他實現不同)。

合理的方法是在InputStream中創建一個子線程循環(即標準輸出;難道你不愛的命名?),具體如下:

while((line = reader.readLine()) != null) 
{ 
    // do stuff 
} 

然而,解壓速度很慢,所以我真正需要的是reader.readLine方法靜靜地等待下一行變爲可用,而不是退出。

有沒有很好的方法來做到這一點?

+1

reader.readLine()正是你想要的。你的實現過早退出嗎? – akarnokd 2009-06-22 16:26:57

回答

2

您應該可以用InputStreamReaderBufferedReader包裝輸入流。然後您可以撥打readLine(),並根據需要阻止。

請注意,您應該有一個相應的stderr閱讀器。你不需要做任何事情,但是你需要使用stderr流,否則你的產生的進程可能會阻塞。請參閱this answer以獲得鏈接等。

1

您或多或少都有自己的解決方案。您只需創建一個新線程,從外部進程的流中讀取循環中的下一行並處理該行。

readLine()將阻塞並等待,直到整個新行可用。如果你使用的是多核/處理器機器,那麼當你的線程處理一條線時,你的外部進程可以繼續解壓縮。至少解壓縮可以繼續,直到OS管道/緩衝區變滿。

請注意,如果你的處理速度比解壓縮慢,你會阻止解壓縮,在這一點上它成爲一個內存vs速度問題。例如你可以創建一個線程,除了讀取行之外什麼都不做,因此解壓縮不會被阻塞,將它們緩存在內存中的一個隊列中,以及另一個線程 - 甚至是多個線程 - 消耗所述隊列。

ReadLine方法來靜靜地等待 下一行(S)成爲 不是退出

可用,第二這正是的readLine應該做的,它只會阻止,直到整個線路可用。

1

是的。

我已經寫了一些代碼在進程(由進程生成器產生)中啓動一個耗時的工作(ffmpeg),並且它反過來啓動我的OutputStreamReader類,它是使用stdio的Thread的擴展,一些神奇的東西。

catch(對我來說)是重定向錯誤流。這裏是我的代碼片段:

 procbbuilder.redirectErrorStream(true); 
     proc = pb.start(); 
     err = new MyOutputStreamReader(this, proc.getInputStream()); //extenion of thread 
     err.start(); 

     int exitCode = proc.waitFor(); 
相關問題