В псевдокоде, вот что я делаю:
Process proc = runtime.exec(command);
processOutputStreamInThread(proc.getInputStream());
processOutputStreamInThread(proc.getErrorStream());
proc.waitFor()
Однако иногда processOutputStreamInThread
не видит никакого вывода, а иногда и делает. Примерно, метод создает BufferedInputStream
выход команды и отправляет его в журнал.
Основываясь на том, что я вижу, я предполагаю, что command
не обязательно иметь все, что он выводит, в потоки, подаваемые getInputStream()
и getErrorStream()
, что позволяет потоку быть пустым.
Результаты моих испытаний следующие вопросы:
(1). waitFor()
в 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()