Код: Выделить всё
public class PipeConnector implements Runnable {
private final Process source;
private final Process target;
private final BufferedReader sourceOutput;
private final BufferedWriter targetInput;
public PipeConnector(Process source, Process target) {
this.source = source;
this.target = target;
sourceOutput = new BufferedReader(new InputStreamReader(source.getInputStream()));
targetInput = new BufferedWriter(new OutputStreamWriter(target.getOutputStream()));
}
private void transmit() throws IOException {
String line;
while ((line = read()) != null && target.isAlive()) {
if (line.isEmpty()) {
if (!target.isAlive()) {
source.destroy();
break;
}
if (!source.isAlive()) {
targetInput.close();
}
} else {
targetInput.write(line + "\n");
targetInput.flush();
}
}
targetInput.close();
}
private String read() throws IOException {
if (sourceOutput.ready()) {
return sourceOutput.readLine();
} else {
return "";
}
}
public void run() {
try {
transmit();
} catch (IOException _) {
}
}
}
Код: Выделить всё
ProcessBuilder cmdTail = new ProcessBuilder(
List.of("tail", "-f", "test.txt"))
.directory(new File("/home/lowkkid/test"));
ProcessBuilder cmdHead = new ProcessBuilder(List.of("head", "-n", "6"));
Process processTail = cmdTail.start();
Process processHead = cmdHead.start();
PipeConnector connector = new PipeConnector(processTail, processHead);
new Thread(connector).start();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(processHead.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
После отладки я понял, что эти 4 строки застревают где-то в целевом процессе, пока их не останется 6. Они успешно записываются в targetInput, но не отображаются в System.out.println(line);. Если я запускаю приложение с файлом test.txt, содержащим 6 или более строк, оно печатает их правильно и завершает работу с кодом 0.
Вопрос: Как заставить эти строки печатать немедленно, до достижения счетчика 6?
P.S. В классе PipeConnector я использую проверку if (sourceOutput.ready()), чтобы избежать блокировки с помощью таких команд, как Tail -f, которые ждут дополнительных входных данных после чтения файла. Без этой проверки readLine() будет блокироваться на неопределенный срок, пока исходный процесс ожидает.
Подробнее здесь: https://stackoverflow.com/questions/798 ... ives-the-e
Мобильная версия