Правильное закрытие Java Process InputStream из getInputStream - PullRequest
25 голосов
/ 17 августа 2011

Я не смог найти разъяснения по этому вопросу в документации.Но когда у нас есть Process объект и вызов getInputStream(),

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

По сути, как мы должны взаимодействовать с потоком, который мы получаем изProcess.getInputStream()?закрывать или не закрывать?

Ответы [ 6 ]

8 голосов
/ 18 августа 2011

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

InputStream is = process.getInputStream()
try {
    // your code
} finally {
    try { is.close(); } catch (Exception ignore) {}
}

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

5 голосов
/ 18 августа 2011

Когда вы звоните Process.getInputStream(), вы получаете существующий поток ввода, который был настроен для процесса. Когда процесс умирает, этот поток ввода , а не автоматически исчезает - думайте о нем как о буфере, из которого вы все еще можете прочитать. Конец процесса может быть закрыт, но ваш конец - нет. Вы несете ответственность за его закрытие, хотя GC в конечном итоге получит его.

Вы также должны закрыть два других: getErrorStream() и getOutputStream().

3 голосов
/ 20 июля 2016

Из прочтения UNIXProcess.java вот что происходит:

Нам нужно различать два состояния: либо процесс еще жив, либо он мертв.

Если процесс живзакрывая OutputStream (переходит к стандартному вводу процесса), вы сообщаете процессу, что для него больше нет входных данных.Закрывая InputStreams (stdout, stderr процесса), процесс больше не может записывать в них (он получит SIGPIPE, если попытается).

Когда процесс умирает, Java буферизирует оставшиеся данные из stdout / stderr,и закройте для вас все три потока (на нем запущен поток «Process Reaper», который уведомляется о смерти процесса).Любая попытка записи в OutputStream не удастся.Чтение из InputStream вернет буферизованные данные, если они есть.Закрытие любого из них не приносит никакой пользы, но также не приносит вреда.(Базовые дескрипторы файлов к этому времени закрыты).

0 голосов
/ 16 ноября 2016

Вы не закрываете потоки, которые вы не открывали - это неприятный побочный эффект.Если вы создали процесс, сначала убейте его, а затем закройте потоки.

0 голосов
/ 18 августа 2011

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

НетJavadoc, который так говорит, есть?

0 голосов
/ 18 августа 2011

Я всегда их закрываю! Я не уверен на 100%, но насколько я знаю, если вы оставите входной поток открытым, файл будет открыт, пока вы его не закроете !! Так что следуйте «стандартным правилам» и закройте его! следуйте примеру: Проблема ProcessFor waitFor () и ограничения на открытие файла

...