在Java中创建命名管道

时间:2015-06-29 14:54:56

标签: java linux named-pipes

我正在尝试使用Java创建命名管道。我正在使用Linux。但是,我遇到了写入管道的问题。

    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"在外部shell上,然后程序继续并将所有内容写出来而不会挂起。奇怪的是,这个程序启动的cat子进程是如何工作的。

编辑:我在子进程上做了一个ps,它的状态是" S"。

1 个答案:

答案 0 :(得分:7)

外部进程具有您需要处理的输入和输出。否则,它们可能会挂起,但它们挂起的确切位置会有所不同。

解决问题的最简单方法是更改​​每次出现的问题:

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

到此:

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

Runtime.exec已过时。改为使用ProcessBuilder。

<强>更新

inheritIO() is shorthand用于将所有进程的输入和输出重定向到父Java进程的输入和输出。您可以改为仅重定向输入,并自己读取输出:

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

然后你需要从process.getInputStream()读取进程的输出。