В моем приложении Java мне нужно выполнить некоторые сценарии в качестве подпроцессов и контролировать вывод на stdout из Java, чтобы я мог реагировать, когда это необходимо, на некоторый вывод.Чтение потока stdout из подпроцесса по мере его появления
Я использую apache commons-exec для создания подпроцесса и перенаправления stdout исполняемого скрипта на входной поток.
Проблема, с которой я столкнулась, заключается в том, что при чтении из потока процесс Java блокируется до завершения выполнения подпроцесса. Я не могу дождаться окончания обработки подпроцесса, но мне нужно прочитать его асинхронно, когда он станет доступным.
Ниже мой Java-код:
public class SubProcessReact {
public static class LogOutputStreamImpl extends LogOutputStream {
@Override
protected void processLine(String line, int logLevel) {
System.out.println("R: " + line);
}
}
public static void main (String[] args) throws IOException, InterruptedException {
CommandLine cl = CommandLine.parse("python printNumbers.py");
DefaultExecutor e = new DefaultExecutor();
ExecuteStreamHandler sh = new PumpStreamHandler(new LogOutputStreamImpl());
e.setStreamHandler(sh);
Thread th = new Thread(() -> {
try {
e.execute(cl);
} catch (IOException e1) {
e1.printStackTrace();
}
});
th.start();
}
}
Для этого примера, подпроцесс является питон скрипт, который подсчитывает вверх с одной секундной задержкой между выходами, так что я могу проверить, что код Java отвечает как данные приходит в
Python код:.
import time
for x in range(0,10):
print x
time.sleep(1)
Я бы ожидать LogOutputStreamImpl печатать каждую строку, как это происходит, но то, что на самом деле происходит, что он считывает потоковые блоки до завершения подпроцесса, а затем печатается весь вывод.
Есть ли что-то, что я мог бы сделать, чтобы сделать эту работу так, как я намерен?
Спасибо за ваш ответ, но это не решает мою проблему. Мне нужно уметь читать каждую строку, когда она входит в поток. С этим решением у меня та же проблема, что и в моем исходном коде, я могу получить весь результат после завершения завершения скрипта. Мне нужно уметь читать каждую строку по мере ее появления. – apatrick
@apatrick: кроме того, чтобы читать одну строку за раз в вашем Java-коде, вам может понадобиться флаг '-u', чтобы отключить буферизацию' python' ' s stdout/stderr. В противном случае, при перенаправлении вывод блокируется блоком. См. [Мой ответ на аналогичный вопрос, но для 'Python'] (http://stackoverflow.com/a/17698359/4279) – jfs
@ J.F.Sebastian Это решило мою проблему. Я не думал, что проблема будет на стороне Python. Большое вам спасибо! – apatrick