В псевдокоде вот что я делаю:
Process proc = runtime.exec(command);
processOutputStreamInThread(proc.getInputStream());
processOutputStreamInThread(proc.getErrorStream());
proc.waitFor()
Однако иногда processOutputStreamInThread
не видит никакого вывода, а иногда и делает. Грубо говоря, метод создает BufferedInputStream
выходных данных команды и отправляет их в логгер.
Исходя из того, что я вижу, я предполагаю, что command
не нужно, чтобы весь вывод выводился в потоки, подаваемые getInputStream()
и getErrorStream()
, что позволяет потоку быть пустым.
Результатами моих испытаний являются следующие вопросы:
(1) Требует ли waitFor()
in java.lang.Process , чтобы вывод выполненной программы был прочитан до того, как он вернется?
В документации указано только:
заставляет текущий поток при необходимости ждать, пока процесс, представленный этим объектом Process
, не будет завершен. Этот метод сразу возвращается, если подпроцесс уже завершен. Если подпроцесс еще не завершен, вызывающий поток будет заблокирован до выхода из подпроцесса.
(2) При каких условиях необходимо закрывать потоки, предоставленные getInputStream
и getErrorStream
, и / или они закрываются автоматически?
В документации указано только:
Получает поток ошибок подпроцесса. Поток получает данные из потока вывода ошибок процесса, представленного этим объектом Process.
Замечание по реализации: рекомендуется буферизовать входной поток.
Один пользователь сообщает , что он сам должен был закрыть потоки, но я получаю исключение, по крайней мере, часть времени, указывающее, что поток уже закрыт, когда я пытаюсь это сделать.
Редактировать: изменено getOutputStream
на getInputStream
, теперь присутствует выше.
Разрешение: Проблема закончилась тем, что в некоторых случаях потоки, используемые для обработки выходного потока, не запускались до тех пор, пока не завершился мой очень недолговечный процесс, в результате чего входной поток дал мне нет данных. waitFor
не ожидал вывода выполненной программы. Скорее программа запускалась и завершалась до того, как какой-либо вывод мог быть собран.
Я использовал потоки, потому что я не уверен, сколько данных я собирался получить при стандартной ошибке и стандартном выводе, и я хотел иметь возможность обрабатывать оба одновременно, без блокировки одного или другого, если только один из них будет иметь данные имеется в наличии. Но, поскольку мои потоки не могут последовательно прочитать вывод исполняемой программы, это не решение.
Мой окончательный код выглядел примерно так:
ProcessBuilder pb = new ProcessBuilder(cmdargs);
pb.redirectErrorStream(true);
Process proc = pb.start();
processOutputStream(proc.getInputStream());
proc.waitFor()