Module (27%)
Section (83%)

Закрытие потока

Последняя операция, выполненная над потоком (это не включает потоки stdin, stdout и stderr, которые не требуют этого), должна быть закрытием.

Это действие выполняется методом, вызываемым из объекта открытого потока: stream.close().

  • имя функции определенно комментируется (close());
  • функция не ожидает точно никаких аргументов; поток не нужно открывать;
  • функция ничего не возвращает, но вызывает IOError в случае ошибки;
  • большинство разработчиков считают, что функция close() всегда выполняется успешно, поэтому нет необходимости проверять, правильно ли она выполнила свою задачу.

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

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

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

Диагностика проблем с потоками

Объект IOError оснащен свойством с именем errno (имя происходит от фразы error number), и Вы можете получить к нему доступ как следующим образом:

try: # Some stream operations. except IOError as exc: print(exc.errno)

Значение атрибута errno можно сравнить с одной из предопределенных символических констант, определенных в модуле errno.




Давайте посмотрим на некоторые выбранные константы, полезные для обнаружения потоковых ошибок:

  • errno.EACCES в доступе отказано.

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

  • errno.EBADF неверный номер файла.

    Ошибка возникает, когда Вы пытаетесь, например, работать с неоткрытым потоком.

  • errno.EEXIST файл существует.

    Ошибка возникает, например, при попытке изменить имя файла на такое же.

  • errno.EFBIG файл слишком большой.

    Ошибка возникает при попытке создать файл, размер которого превышает максимально допустимый операционной системой.

  • errno.EISDIR это каталог.

    Ошибка возникает при попытке трактовать имя каталога как имя обычного файла.

  • errno.EMFILE слишком много открытых файлов.

    Ошибка возникает при попытке одновременно открыть больше потоков, чем приемлемо для вашей операционной системы.

  • errno.ENOENT нет такого файла или каталога.

    Ошибка возникает при попытке доступа к несуществующему файлу/каталогу.

  • errno.ENOSPC на устройстве не осталось места.

    Ошибка возникает, когда на носителе нет свободного места.

Полный список намного длиннее (он также включает некоторые коды ошибок, не связанные с обработкой потока).