2011-08-17 4 views
19

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

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

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

ответ

8

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

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

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

+3

IOUtils.closeQuietly (is) позаботится о попытке {is.close(); } catch (Exception ignore) {} – Kirby

0

Я всегда их закрываю! Я не уверен на 100%, но насколько я знаю, если вы оставите входной поток открытым, файл будет открыт, пока вы его не закроете !! Поэтому следуйте «стандартным правилам» и закройте его! следуйте примеру: Process Builder waitFor() issue and Open file limitations

5

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

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

+0

«Когда процесс умирает, этот поток ввода не исчезает автоматически» - когда вы запускаете процесс, Java запускает поток «process reaper», который закрывает локальную сторону таких каналов в Это дело. –

0

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

Нет Джавадока, который так говорит, не так ли?

2

От чтения UNIXProcess.java, это то, что происходит:

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

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

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

0

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

Смежные вопросы