Process.waitFor (), потоки и InputStreams

В псевдокоде вот то, что я делаю:

Process proc = runtime.exec(command);
processOutputStreamInThread(proc.getInputStream());
processOutputStreamInThread(proc.getErrorStream());
proc.waitFor()

Однако иногда processOutputStreamInThread не видит вывода, и иногда он делает. Примерно, метод создает a BufferedInputStream из вывода команды и отправляет его на регистратор.

На основе того, что я вижу, я предполагаю это command не должен иметь всего, чем это произвело выведенный в потоки, питаемые getInputStream() и getErrorStream(), таким образом позволяя потоку быть пустым.

Результатами моих пробных версий являются следующие вопросы:

(1) Делает waitFor() в java.lang. Процесс требует, чтобы вывод выполненной программы был считан, прежде чем он возвратится?

Документация только указывает:

заставляет текущий поток ожидать, при необходимости, до процесса, представленного этим Process объект завершился. Этот метод сразу возвращается, если подпроцесс уже завершился. Если подпроцесс еще не завершился, вызывающий поток будет заблокирован до выходов подпроцесса.

(2) При каких условиях делают потоки, обеспеченные getInputStream и getErrorStream потребность, которая будет закрыта, и/или они закрываются автоматически?

Документация только указывает:

Получает поток сообщений об ошибках подпроцесса. Поток получает данные, переданные по каналу из потока вывода ошибок процесса, представленного этим объектом Процесса.

Примечание реализации: Это - хорошая идея для входного потока, который будет буферизован.

Один пользователь сообщает, что должен был закрыть потоки сам, но я получаю исключение, по крайней мере, часть времени, указывая, что поток уже закрывается, когда я пытаюсь сделать так.

Править: измененный getOutputStream кому: getInputStream, теперь существующий выше.

Разрешение: проблема закончила тем, что была, что в определенных случаях потоки, используемые для обработки потока вывода, не будут работать, пока мой очень недолгий процесс не завершился, приведя к входному потоку, дающему мне никакие данные. waitFor не сделал никакого ожидания вывода выполненной программы. Скорее программа работала и завершилась, прежде чем любой вывод мог быть собран.

Я использовал потоки, потому что я не уверен, насколько произведенный я собирался войти в стандартную погрешность и стандартный вывод, и я хотел смочь обработать, оба одновременно, не блокируясь один или другой должны только один из них иметь доступные данные. Но, потому что мои потоки не могут последовательно читать вывод выполненной программы, это - нерешение.

Мой кодированный финал выглядел примерно так:

ProcessBuilder pb = new ProcessBuilder(cmdargs);
pb.redirectErrorStream(true);
Process proc = pb.start();
processOutputStream(proc.getInputStream());
proc.waitFor()

32
задан Community 23 May 2017 в 12:32
поделиться

2 ответа

Если Ваш внешний процесс ожидает чего-то от своего stdin, то Вы ДОЛЖНЫ закрыть getOutputStream. В противном случае вы будете ожидать вечно.

Вот When Runtime.exec() не будет писать статью из JavaWorld, которая описывает различные "подводные камни" метода exec и как их избежать.

По моему опыту лучше использовать STDOUT и STDERR дочернего процесса ( до тех пор пока они не EOF ), а затем заблокировать в waitFor. Надеюсь, что в этот момент вам не придется долго ждатьFor.

Ответ на вопрос Калеба. При нормальных условиях вы не должны закрывать потоки, однако, потому что вы waitFor и по какой-то причине у него нет таймаута, вам может понадобиться закрыть эти потоки, если вы столкнетесь с какими-то условиями ошибки в выводе и не захотите обрабатывать далее вывод дочерних потоков. Однако, будет ли дочерняя программа завершаться (аварийно завершаться), когда на другом конце закрыт канал STDOUT или STDERR, полностью зависит от реализации этого дочернего процесса. Однако большинство оболочек программ завершает свою работу при таких условиях.

Мне бы очень хотелось, чтобы в waitFor было какое-то осмысленное время ожидания, а в Process был задокументирован способ очистки своих ресурсов, когда вы решили отказаться от его мониторинга.

29
ответ дан 27 November 2019 в 21:10
поделиться

Я думаю, что это слегка противоборбилие, но:

GetOutPutStream получает вывод поток подпроцесса. Вывод к Поток работает в стандарт входной поток процесса представлен этим процессом объектом. Реализация Примечание: это хорошая идея для выходного потока для буферизации. Возвращает: выходной поток подключен к нормальному входу подпроцесса.

Я прочитал, что в качестве этого выходного потока из основного процесса и прикреплен к стандартному входу подпрограмма, поэтому при записи в getOutputtream (). Написать () Вы на самом деле пишу на stdin.

Вы, возможно, хотите использовать .getinputStream ()?

Возвращает: Входной поток подключен к нормальному выходу подпроцесса.

Что касается процесса. Waitfor () Документы API говорят:

вызывает нынешнюю резьбу ждать, если необходимо, до тех пор, пока процесс Представлен этот процесс объекта имеет прекращено. Этот метод возвращает немедленно, если бы подпроцесс уже прекращено. Если подпроцесс еще не прекратил, вызывая Тема будет заблокирована до Субпроцесс выходит.

Я бы сказал, что тема, которая вызывается, будет заблокирована до такой времени, как процесс завершится выполнением - вы все равно можете быть обработке вывода на этом этапе в зависимости от других потоков, или они могут закончиться до возвращения вашего потока.

2
ответ дан 27 November 2019 в 21:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: