在 Java 中创建命名管道
Creating named pipes in Java
我正在尝试使用 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"。
外部进程有您需要处理的输入和输出。否则,它们可能会挂起,尽管它们挂起的确切点会有所不同。
解决问题的最简单方法是更改每次出现的问题:
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() 中读取进程的输出。
我正在尝试使用 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"。
外部进程有您需要处理的输入和输出。否则,它们可能会挂起,尽管它们挂起的确切点会有所不同。
解决问题的最简单方法是更改每次出现的问题:
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() 中读取进程的输出。