2016-07-23 40 views
0

將數據從java發送到由(ProcessBuilder/Process創建的)(linux)子過程時出現問題。作爲管道寫入到Java Process/ProcessBuilder的OutputStream中

基於shell的基本示例如下所示,工作正常。

echo "hello world" | cat - >/tmp/receive.dat 

現在,我想通過一個Java程序,它應該在內部創建一個新的進程(cat - >/tmp/receive.dat),然後將數據發送給它取代echo "hello world"

我嘗試以下,但該文件/tmp/receive.dat保持不變:

String[] cmdArray = { "/bin/cat", "-", ">/tmp/receive.dat" }; 
ProcessBuilder builder = new ProcessBuilder (cmdArray); 
builder.directory (new File ("/tmp")); 
Process p = builder.start(); 
OutputStream pos = p.getOutputStream(); 

byte [] bytes = "hello world".getBytes(); 
pos.write (bytes); 
pos.close(); 
p.waitFor(); 

同樣的情況,在Windows下,當然有適合cmdArray:

cmd /c type con >c:\tmp\receive.dat 

打印直接從System.out的java是沒有其他選擇的,因爲在java程序的生命週期中應該調用許多子進程。

thx任何幫助! Tombo

回答

1

這裏的問題是/bin/cat實際上沒有寫入文件,它只是寫入標準輸出。輸出重定向>/tmp/receive.dat實際上是由shell執行的,但您通過以這種方式調用cat來繞過shell。

如果您試圖實現的僅僅是一個輸出流寫入文件,那麼通過標準的Java I/O(例如FileOutputStream和朋友)來做到這一點是您想要的。它也是跨平臺的(即Windows友好的),不像任何依賴於shell的東西。

關於不能僅僅因爲子進程而從java寫出標準輸出的評論 - 你調用的任何子進程都可以從他們的父進程(java進程 - 看看ProcessBuilder.Redirect.INHERIT)繼承標準。所以,即使你從java中調用子進程,將所有輸出重定向到一個文件仍然應該和你最初的例子一樣工作(java程序替換echo命令)。

+0

很奇怪!當然,輸出重定向是由shell完成的,但我們在這裏沒有任何shell,所以> /tmp/receive.dat被作爲參數發送給cat ...我用另一個receiver-command(ghostscript)精細! –

+0

ghostscript本身可能有一些特殊的邏輯,它將「> file」解釋爲「寫入文件」,但是cat沒有這樣的功能(它總是簡單地寫入標準輸出)。我花了一分鐘尋找一個與貓相反的命令(將標準輸入寫入名爲參數的文件),但沒有看到這樣的事情。 – thewmo

-1

您可能想要ProcessBuilder#redirectOutput(File),因爲>功能不是貓,而是什麼叫貓(在我們的意義上,過程建設者)。

+0

它是命令外殼的一個功能。無論是「貓」還是流程構建者,都沒有什麼可做的。 – EJP