Рубрики
Без рубрики

Python: Проверьте, существует ли файл или каталог

Автор оригинала: Scott Robinson.

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

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

drwxr-xr-x  3 scott  staff  102 Jan 12 10:01 dir
-rw-r--r--  1 scott  staff    5 Jan 12 09:56 file.txt
lrwxr-xr-x  1 scott  staff    8 Jan 12 09:56 link.txt -> file.txt
lrwxr-xr-x  1 scott  staff    3 Jan 12 10:00 sym -> dir

Обратите внимание, что у нас есть один каталог ( dir ), один файл ( file.txt ), одна файловая символическая ссылка ( link.txt ), и одна символьная ссылка каталога ( sym ).

Проверка наличия файла

Это, пожалуй, самый простой способ проверить, существует ли файл и , если это файл.

import os
os.path.isfile('./file.txt')    # True
os.path.isfile('./link.txt')    # True
os.path.isfile('./fake.txt')    # False
os.path.isfile('./dir')    # False
os.path.isfile('./sym')    # False
os.path.isfile('./foo')    # False

Обратите внимание, что os.path.isfile следует за символическими ссылками, поэтому мы получаем True при проверке link.txt .

is file на самом деле является просто вспомогательным методом, который внутренне использует os.stat и stat.S_IS REG(mode) внизу, которого мы коснемся позже.

Проверка наличия каталога

Как и метод isfile , os.path.isdir – это самый простой способ проверить, существует ли каталог или данный путь является каталогом.

import os
os.path.isdir('./file.txt')    # False
os.path.isdir('./link.txt')    # False
os.path.isdir('./fake.txt')    # False
os.path.isdir('./dir')    # True
os.path.isdir('./sym')    # True
os.path.isdir('./foo')    # False

Опять же, как и isfile , os.path.isdir следует за символическими ссылками. Это также просто простая оболочка вокруг os.stat и stat.S_ISDIR(mode) , так что вы не получаете от нее ничего, кроме удобства.

Проверка Того, Существуют Ли Они

Другой способ проверить, существует ли путь (если вам все равно, указывает ли он на файл или каталог), – это использовать os.path.exists .

import os
os.path.exists('./file.txt')    # True
os.path.exists('./link.txt')    # True
os.path.exists('./fake.txt')    # False
os.path.exists('./dir')    # True
os.path.exists('./sym')    # True
os.path.exists('./foo')    # False

Как видите, ему все равно, указывает ли путь на файл, каталог или символическую ссылку, так что это почти то же самое, что вы используете isfile(path) или isdir(path) . Но на самом деле внутренне он просто пытается вызвать os.stat(path) , и если возникает ошибка , то он возвращает False .

Передовой

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

Как и все другие методы, которые мы уже рассмотрели, os.stat следует за символическими ссылками, поэтому, если вы хотите получить информацию о статистике по ссылке, попробуйте использовать os.lstat() вместо этого.

Поскольку каждая операционная система отличается, данные, предоставляемые os.stat , сильно различаются. Вот лишь некоторые из данных, которые объединяет каждая ОС:

  • st_mode : биты защиты
  • st_uid : идентификатор пользователя владельца
  • st_gid : идентификатор группы владельца
  • st_size : размер файла в байтах
  • st_atime : время последнего доступа
  • st_mtime : время последней модификации
  • st_ctime : время последнего изменения метаданных в Unix или время создания в Windows

Затем вы можете использовать эти данные с модулем stat , чтобы получить интересную информацию, например, указывает ли путь на сокет ( stat.S_ISSOCK(mode) ) или если файл на самом деле является именованным каналом ( stat.S_ISFIFO(mode) ).

Если вам нужна более продвинутая функциональность, то именно сюда вам и следует обратиться. Но в течение 90% времени, когда вы имеете дело с каталогами и файлами, модули os или os.path должны охватывать вас.

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