我希望能夠從Java產生一個外部進程,並定期寫入其輸入並讀取響應,就好像它是控制檯一樣。然而,大多數時候,當我讀取過程的輸出時,沒有任何東西可用。有沒有一種很好的做法來做這種事情(甚至避免它)?如何可靠地讀寫從Java運行的外部進程?
這裏有什麼行不通一個精簡例如:
import org.apache.commons.exec.*;
import java.io.*;
//...
CommandLine cl = CommandLine.parse("/usr/bin/awk {print($1-1)}");
System.out.println(cl.toStrings());
Process proc = new ProcessBuilder(cl.toStrings()).start();
OutputStream os = proc.getOutputStream(); // avoiding *Buffered* classes
InputStream is = proc.getInputStream(); // to lessen buffering complications
os.write(("4" + System.getProperty("line.separator")).getBytes());
os.flush(); // Doesn't seem to flush.
// os.close(); // uncommenting works, but I'd like to keep the process running
System.out.println("reading");
System.out.println(is.read()); // read even one byte? usually is.available() -> 0
奇怪的是,如果我包裹起來的OutputStream中的BufferedWriter中,我可以從一些過程(貓)閱讀,而不是其他( awk,grep)。
查看我的答案,如果它有幫助,http://stackoverflow.com/questions/13008526/runtime-getruntime-execcmd-hanging/13008847#13008847 – Arham
謝謝,阿罕姆。我沒有考慮過stdErr可能會填滿並消除同步問題是一個不錯的方法。儘管如此,在單獨的線程中從stdErr中讀取這些信息並沒有幫助。我希望能夠將數據推送到流程,讓流程工作 - 例如處理流水線或等待任何響應,然後繼續前進,如從shell運行。我應該用bash -c「...」來包裝我的外部過程嗎? – jlb
我還沒有嘗試過運行unix進程,但在java中的Windows進程,你必須嘗試一下。但據我所知,您希望自己控制應用程序的退出,而不是系統。爲此,你總是可以把proc.destroy()放入一個自定義的條件中。 – Arham