2015-06-29 49 views
3

我正在嘗試使用Java創建命名管道。我正在使用Linux。但是,我遇到了寫入管道的問題。在Java中創建命名管道

File fifo = fifoCreator.createFifoPipe("fifo"); 
    String[] command = new String[] {"cat", fifo.getAbsolutePath()}; 
    process = Runtime.getRuntime().exec(command); 

    FileWriter fw = new FileWriter(fifo.getAbsoluteFile()); 
    BufferedWriter bw = new BufferedWriter(fw); 
    bw.write(boxString); //hangs here 
    bw.close(); 
    process.waitFor(); 
    fifoCreator.removeFifoPipe(fifo.toString()); 

fifoCreator:

@Override 
public File createFifoPipe(String fifoName) throws IOException, InterruptedException { 
    Path fifoPath = propertiesManager.getTmpFilePath(fifoName); 
    Process process = null; 
    String[] command = new String[] {"mkfifo", fifoPath.toString()}; 
    process = Runtime.getRuntime().exec(command); 
    process.waitFor(); 
    return new File(fifoPath.toString()); 
} 

@Override 
public File getFifoPipe(String fifoName) { 
    Path fifoPath = propertiesManager.getTmpFilePath(fifoName); 
    return new File(fifoPath.toString()); 
} 

@Override 
public void removeFifoPipe(String fifoName) throws IOException { 
    Files.delete(propertiesManager.getTmpFilePath(fifoName)); 
} 

我寫的是由1000行的字符串。寫100行工作,但1000行不行。

但是,如果我在外殼上運行「cat fifo」,那麼程序就會繼續執行,並且不會掛起。奇怪的是,這個程序啓動的cat子進程無法工作。

編輯:我在子進程上做了一個ps,它有狀態「S」。

回答

6

外部進程有您需要處理的輸入和輸出。否則,他們可能會掛起,儘管他們掛在哪個位置的確切點是不一樣的。

解決您的問題,最簡單的方法就是改變這種每次發生:

process = Runtime.getRuntime().exec(command); 

這樣:

process = new ProcessBuilder(command).inheritIO().start(); 

的Runtime.exec已經過時了。改用ProcessBuilder。

UPDATE:

inheritIO() is shorthand所有過程的輸入和輸出的重定向與那些親本的Java程序。您可以自己,而不是重定向只有輸入和讀取輸出:

process = new ProcessBuilder(command).redirectInput(
    ProcessBuilder.Redirect.INHERIT).start(); 

然後,你將需要從process.getInputStream讀取過程的輸出()。

+0

This Works。但是,如何獲得流程的輸出?在此之前,我使用了process.getInputStream()。 – mrQWERTY

+0

如果您知道您將通過process.getInputStream()讀取輸出,您可以選擇僅重定向進程的輸入。相應地更新答案。 – VGR