5/5 - (1 голос)

В программировании есть несколько способов решить задачу, и особенно это верно в 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.

isfile, по сути, просто вспомогательный метод, который внутри использует os.stat и stat.S_ISREG(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: пользовательский id владельца
  • st_gid: групповой id владельца
  • st_size: размер файла в байтах
  • st_atime: время ближайшего доступа
  • st_mtime: время ближайшего изменения
  • st_ctime: время ближайшего изменения метаданных в Unix, или время создания в Windows

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

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

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

ОСТАВЬТЕ ОТВЕТ

Please enter your comment!
Please enter your name here