Почему хорошо закрыть() входной поток?
У меня есть звук на языке программирования Java. Но одна вещь, которая всегда была в моем сознании, состоит в том, почему это необходимо для close()
java.io.InputStream
или его подклассов?
Теперь, когда java.io.OutputStream
, скажем FileOutputStream
, после записи в файл, если мы не close()
поток вывода, данные, которые мы намеревались записать в файле, остаются в буфере и не записываются к файлу.
Таким образом, становится необходимым close()
a OutputStream
. Но у меня никогда не было каких-либо горьких переживаний после не закрытия a InputStream
.
Но все же все статьи в Интернете и в книгах говорят, что всегда полезно закрыть любой поток, возможно, это InputStream
или OutputStream
.
Итак, мой вопрос в том, почему возникает необходимость close()
a InputStream
? Люди говорят, что вы можете столкнуться с утечкой памяти, вы не close()
. Итак, какова утечка памяти?
Ответы
Ответ 1
InputStream связывает крошечный ресурс ядра, дескриптор файла низкого уровня. Кроме того, файл будет заблокирован в некоторой степени (от удаления, переименования), если вы его открываете для чтения. Предположим, вы не заботитесь о заблокированном файле. В конце концов, если вам нужно прочитать другой файл и открыть его с помощью нового InputStream, ядро последовательно выделяет для вас новый дескриптор (поток файлов). Это будет добавлено.
Это просто вопрос времени, когда сбой программы для долгого приложения.
Таблица дескрипторов файлов для процессора имеет ограниченный размер. В конечном итоге таблица дескриптора файла закончится свободными слотами для процесса. Даже в тысячах вы все равно можете легко исчерпать это для долгого приложения, и в этот момент ваша программа больше не может открывать новый файл или сокет.
Таблица дескрипторов файла процесса упрощена, например:
IOHANDLE fds[2048]; // varies based on runtime, IO library, etc.
Вы начинаете с 3 слотов, занятых. Заполните это, и вы выполнили отказ в обслуживании самостоятельно.
Ответ 2
Это не утечка памяти, а утечка файла. Операционная система позволяет только одному процессу открывать определенное количество файлов, а если вы не закрываете свои входные потоки, это может запретить JVM больше открываться.
Ответ 3
Это потенциальная утечка ресурсов. Наследование не позволяет точно узнать, какой ресурс может быть просочился, когда вы задаете этот вопрос таким образом. Например, я мог бы написать свой собственный класс под названием VoidInputStream, который не выделяет ресурсов, требующих закрытия. Но если вы не закрываете его, вы нарушаете унаследованный контракт.
См. http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html Список различных входных потоков.
Тестирование утечек ресурсов, как известно, сложно. Во-вторых, только для тестирования проблем concurrency. Не будьте так уверены, что вы неосознанно вызвали небольшой хаос.
Ответ 4
Может быть любое количество ресурсов ОС, связанных с InputStream, например, с открытыми файлами или сокетами. A close() освободит эти ресурсы.
Ваша программа не должна знать, с какими типами InputStream она работает. Он просто должен придерживаться договора о том, что поток закрыт после использования, так что любые ресурсы могут быть освобождены.