Creating named pipes in Java

I am experimenting with creating named pipes using Java. I am using Linux. However, I ran into a problem when the recording on the tube hangs.

    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));
}

      

I am writing a line that is 1000 lines long. Writing 100 lines works, but 1000 lines doesn't.

However, if I run "cat fifo" on the outer shell, the program continues and writes everything without hanging. Its strange how the cat subprocess started by this program doesn't work.

EDIT: I made ps on a subprocess and it has an "S" status.

+3


source to share


1 answer


External processes have input and output that you need to handle. Otherwise, they may hang, although the exact point at which they hang varies.

The easiest way to solve your problem is to change every occurrence of this:

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

      

:

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

      



Runtime.exec is deprecated. Use ProcessBuilder instead.

UPDATE:

inheritIO () is shorthand for redirecting all input and output of a process to the parent Java process. Instead, you can only redirect the input and read the result yourself:

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

      

Then you will need to read the process output from process.getInputStream ().

+6


source







All Articles