Подтвердить что ты не робот

Почему объявлен InputStream.close() для сброса IOException?

Объявлен способ java.io.InputStream.close() выбросить IOException. При каких обстоятельствах действительно будет исключено такое исключение?

Изменить: Да, я прочитал javadoc. Может ли кто-нибудь быть более конкретным, чем "когда возникает ошибка ввода-вывода"? Какая ошибка ввода-вывода может произойти при закрытии InputStream?

4b9b3361

Ответ 1

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

В случае чтения входного потока из сетевого соединения ошибка при закрытии является более понятной. Нормальное закрытие сетевого сокета фактически включает в себя запрос на закрытие (пакет TCP/IP FIN), отправляемый по соединению, и ожидание того, что другой конец подтвердит этот запрос на закрытие. (Фактически, другой конец соединения затем, в свою очередь, отправляет запрос на закрытие, который подтверждает завершающий конец.) Таким образом, в случае входного потока сокета операция закрытия фактически включает в себя передачу трафика по соединению, и замыкание может, таким образом, с ошибкой.

Обратите внимание, что во многих реализациях close() обычно не бросает IOException, если поток уже закрыт; он просто терпит неудачу, чтобы закрыть поток снова.

Ответ 2

Я просматриваю исходный код Java и нашел что-то интересное, что свидетельствует о причине IOException. InputStream - абстрактный класс. Поэтому мы не можем предсказать тип ввода, который будет закрыт, поэтому хорошо поддерживать поток информации.

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

Важно понимать расположение структуры исключений в Java. Разумеется, каждое исключение распространяется на Exception. Тем не менее, существуют также более широкие категории исключений: java.lang.IOException является одним из них и охватывает все возможные исключения ввода/вывода. Когда мы говорим, что была ошибка ввода-вывода, мы ссылаемся на все, что подпадает под IOException. В результате многие исключения расширяют этот вариант, например. FileNotFoundException, EOFException и т.д., поскольку важно иметь широкое, всеобъемлющее исключение для управления ими.

В результате любой класс IO должен будет иметь возможность запускать любое из различных IOExceptions при закрытии. close() поэтому должен бросать IOException - это дает своей реализации возможность бросить любое из расширений IOException. Вот почему close() throws IOException - исключения наследуются, и вы должны иметь возможность любого из IOExceptions при закрытии потока.


Вот несколько сценариев, которые стоит отметить:

  • Вы не можете закрыть IOStream дважды, хотя это обычно не вызывает исключения, если вы делаете
  • Содержимое становится недоступным (например, диск был отключен) (close() на самом деле имеет решающее значение для операционной системы, так как он должен иметь индикатор того, когда файл больше не занят)
  • Общий источник закрыт
  • Любой общий отказ, не охватываемый всеми другими подклассами IOException (например, FileNotFoundException)

Вы можете проверить, что вызвало IOException, запустив Exception.getMessage().

Ответ 3

Заключительный закрытый системный вызов должен быть выполнен в конце концов, например. на linux http://linux.die.net/man/2/close. Этот вызов документирован с ошибкой с EIO: "Произошла ошибка ввода-вывода". Поэтому причина в том, что вызов файловой системы close может завершиться неудачно.

Ответ 4

Я подумал об этом сам и несколько лет назад провел небольшое исследование по этой теме. Это то, что я знаю....

Если вы посмотрите на javadoc в приведенной вами ссылке, в нем четко сказано, что "метод Close из InputStream ничего не делает", поэтому нет способа, чтобы он выдавал исключение, правильно? Но затем, глядя на все подклассы IOException, вы увидите, что существует множество ситуаций, когда подклассы входного потока могут не иметь возможности закрыть поток. Поэтому я полагаю, что это исключение предназначено для использования подклассами.

http://docs.oracle.com/javase/6/docs/api/java/io/IOException.html

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