Закрытие потока
Последняя операция, выполненная над потоком (это не включает потоки 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→ на устройстве не осталось места.
Ошибка возникает, когда на носителе нет свободного места.
Полный список намного длиннее (он также включает некоторые коды ошибок, не связанные с обработкой потока).