2015-06-29 50 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