Проверка наличия файла или каталога по указанному пути
Бывает, что надо проверить корректность введенного пользователем адреса файла или каталога. Сделать это можно с помощью функции os.path.exists , которая возвращает true , если объект файловой системы существует, и false – если нет.
Функция os.path.isfile проверяет, является ли объект файлом, а os.path.isdir — является ли каталогом.
В приведенном ниже скрипте проверяется наличие объекта по указанному пользователем адресу, после этого проверяется файл это или каталог. В зависимости от типа объекта выводится информация.
# Скрипт проверяет наличие пути. # Если файл, то выводит его размер, даты создания, открытия и модификации. # Если каталог, выводит список вложенных в него файлов и каталогов. import os import datetime test_path = input('Введите адрес: ') if os.path.exists(test_path): if os.path.isfile(test_path): print('ФАЙЛ') print('Размер:', os.path.getsize(test_path) // 1024, 'Кб') print('Дата создания:', datetime.datetime.fromtimestamp( int(os.path.getctime(test_path)))) print('Дата последнего открытия:', datetime.datetime.fromtimestamp( int(os.path.getatime(test_path)))) print('Дата последнего изменения:', datetime.datetime.fromtimestamp( int(os.path.getmtime(test_path)))) elif os.path.isdir(test_path): print('КАТАЛОГ') print('Список объектов в нем: ', os.listdir(test_path)) else: print('Объект не найден')
В скрипте также используются функции os.path.getsize (возвращает размер файла), os.path.getctime (время создания), os.path.getatime (время последнего открытия), os.path.getmtime (дата последнего изменения). Метод datetime.datetime.fromtimestamp позволяет выводить время в местном формате.
В скрипте также используются функции os.path.getsize (возвращает размер файла), os.path.getctime (время создания), os.path.getatime (время последнего открытия), os.path.getmtime (дата последнего изменения). Метод datetime.datetime.fromtimestamp позволяет выводить время в местном формате.
Примеры выполнения программы:
Введите адрес: /home/pl/test.py ФАЙЛ Размер: 2 Кб Дата создания: 2021-10-14 19:55:58 Дата последнего открытия: 2022-04-21 08:21:00 Дата последнего изменения: 2021-10-14 19:55:58
Введите адрес: /home/pl/pas КАТАЛОГ Список объектов в нем: ['vk', 'theory', 'tasks']
Rukovodstvo
статьи и идеи для разработчиков программного обеспечения и веб-разработчиков.
Python: проверьте, существует ли файл или каталог
Есть довольно много способов решить проблему в программировании, и это особенно актуально для Python [/ why-beginners-should-learn-python /]. Часто вы обнаружите, что несколько встроенных или стандартных модулей служат, по сути, одной цели, но с немного различающейся функциональностью. Проверка наличия файла или каталога с помощью Python, безусловно, является одним из таких случаев. Вот несколько способов проверить существующие файлы / каталоги и их нюансы. В этих примерах мы будем предполагать, что наша валюта
Время чтения: 3 мин.
Есть довольно много способов решить проблему в программировании, и это особенно актуально для 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) or 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.path должны os или os.path.
Хотя один допустимый вариант использования может быть, когда вы выполняете несколько тестов в одном файле и хотите избежать накладных расходов на системный вызов stat для каждого теста. Так что, если вам нужно сделать несколько тестов, это поможет вам сделать это более эффективно.
Licensed under CC BY-NC-SA 4.0
Определение существования пути средствами pathlib
Описанные ниже методы позволяют определить существования пути, а так же тип указанного пути в файловой системе. Данные методы принадлежат экземпляру, созданному из класса Path() .
Так как класс pathlib.Path() наследуется от класса pathlib.PurePath() , следовательно он поддерживает все операции по манипуляции с путями файловой системы.
Смотрите другие методы и свойства, доступные экземпляру класса Path() модуля pathlib .
Содержание:
- Проверить существование какого либо пути.
- Проверить наличие каталога.
- Проверить наличие файла.
- Проверить наличие соединения.
- Проверить наличие точки монтирования ФС.
- Проверить наличие символической ссылки.
- Проверить наличие сокета Unix.
- Проверить наличие устройства FIFO.
- Проверить наличие блочного устройства.
- Проверить наличие символьного устройства.
Path.exists(*, follow_symlinks=True) :
Метод Path.exists() проверяет существование пути path файловой системы. Другими словами, указывает ли путь к существующему файлу или каталогу.
Этот метод обычно следует по символическим ссылкам. Для проверки существования символической ссылки, а не конечного файла, нужно добавить аргумент follow_symlinks=False (добавлен в Python 3.12).
>>> from pathlib import Path >>> Path('.').exists() # True >>> Path('setup.py').exists() # True >>> Path('/etc').exists() # True >>> Path('nonexistentfile').exists() # False
Примечание. Если путь path указывает на символическую ссылку, то метод Path.exists() возвращает информацию о том, указывает ли символическая ссылка на существующий файл или каталог.
Изменено в Python 3.12: добавлен аргумент follow_symlinks .
Path.is_dir() :
Метод Path.is_dir() вернет True , если путь path указывает на каталог, или символическую ссылку, указывающую на каталог. Метод вернет False если путь указывает на файл другого типа.
Значение False также возвращается, если путь не существует или является неработающей символической ссылкой. Метод может вернуть False при отсутствии доступа к директории или символической ссылке, указывающей на директорию.
>>> from pathlib import Path >>> Path('/some/to/directory').is_dir() # True >>> Path('/some/to/file.ext').is_dir() # False >>> Path('/some/to/symlink').is_dir() # False
Path.is_file() :
Метод Path.is_file() вернет True , если путь path указывает на файл или символическую ссылку, указывающую на обычный файл. Метод вернет False , если путь указывает на файл другого типа.
Значение False также возвращается, если путь не существует или является неработающей символической ссылкой. Метод может вернуть False при отсутствии доступа к файлу или символической ссылке, указывающей на файл.
>>> from pathlib import Path >>> Path('/some/to/directory').is_file() # False >>> Path('/some/to/file.ext').is_file() # True >>> Path('/some/to/symlink').is_file() # False
Path.is_junction() :
Метод Path.is_junction() вернет True , если путь Path указывает на соединение, и значение False для любого другого типа файла.
В настоящее время только Windows поддерживает соединения.
Path.is_mount() :
Метод Path.is_mount() вернет True , если путь path является точкой монтирования в файловой системе, где смонтирована другая файловая система.
В POSIX метод проверяет, находится ли родительский путь path/.. на устройстве, отличном от path или path/.. и path указывают на однy и ту же ноду i-node на одном и том же устройстве — это должно определять точки монтирования для всех вариантов Unix и POSIX.
В Windows точкой монтирования считается корневая буква диска (например, c:\ ), общий ресурс UNC (например, \\server\share ) или подключенный каталог файловой системы.
Изменено в Python 3.12: добавлена поддержка Windows.
>>> from pathlib import Path >>> Path('/some/to/directory').is_mount() # False >>> Path('/some/to/mount').is_mount() # True >>> Path('/some/to/file.ext').is_mount() # False
Path.is_symlink() :
Метод Path.is_symlink() вернет True , если путь path указывает на символическую ссылку, иначе вернет False .
Значение False также возвращается, если путь path не существует. Метод может вернуть False при отсутствии доступа к символической ссылке.
>>> from pathlib import Path >>> Path('/some/to/directory').is_symlink() # False >>> Path('/some/to/file.ext').is_symlink() # False >>> Path('/some/to/symlink').is_symlink() # True
Path.is_socket() :
Метод Path.is_socket() вернет True , если путь path указывает на сокет Unix или символическую ссылку, указывающую на сокет Unix. Метод вернет False , если путь указывает на файл другого типа.
Значение False также возвращается, если путь не существует или является неработающей символической ссылкой. Метод может вернуть False при отсутствии доступа к сокету Unix или символической ссылке, указывающей на сокет.
Path.is_fifo() :
Метод Path.is_fifo() вернет True , если путь path указывает на FIFO или символическую ссылку, указывающую на FIFO. Метод вернет False , если путь указывает на файл другого типа.
Значение False также возвращается, если путь не существует или является неработающей символической ссылкой. Метод может вернуть False при отсутствии доступа к FIFO или символической ссылке, указывающей на FIFO.
Path.is_block_device() :
Метод Path.is_block_device() вернет True , если путь path указывает на блочное устройство или символическую ссылку, указывающую на блочное устройство. Метод вернет False , если путь указывает на файл другого типа.
Значение False также возвращается, если путь не существует или является неработающей символической ссылкой. Метод может вернуть False при отсутствии доступа к блочному устройству или символической ссылке, указывающей на блочное устройство.
Path.is_char_device() :
Метод Path.is_char_device() вернет True , если путь path указывает на символьное устройство или символическую ссылку, указывающую на символьное устройство. Метод вернет False , если путь указывает на файл другого типа.
Значение False также возвращается, если путь не существует или является неработающей символической ссылкой. Метод может вернуть False при отсутствии доступа к символьному устройству или символической ссылке, указывающей на символьное устройство.
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Класс pathlib.PurePath() и его подклассы
- Класс pathlib.Path() и его подклассы
- Манипуляции с путями файловой системы средствами pathlib
- Проверить наличие файла/каталога/ссылки и т.д. средствами pathlib
- Открытие файла, чтение и запись информации средствами pathlib
- Определение положения в файловой системе средствами pathlib
- Список файлов в папке/каталоге по шаблону средствами pathlib
- Создание/удаление файла/каталога или ссылки средствами pathlib
- Получение информации о файле/каталоге средствами pathlib
- Изменение режима доступа к файлу или каталогу средствами pathlib
- Переименование/замена файла или каталога средствами pathlib
- Преобразование объекта пути pathlib в строку
- Метод walk() модуля pathlib, рекурсивный обход каталога
- Сравнение pathlib с модулями os и os.path
Как проверить существование файла?
Для проверки существования заданного пути используйте функцию os.path.exists :
import os.path os.path.exists(file_path)
Но она вернет True и для файла и для директории.
os.path.isfile проверит именно на наличие файла.
Отслеживать
ответ дан 7 апр 2015 в 16:46
757 1 1 золотой знак 6 6 серебряных знаков 15 15 бронзовых знаков
Кратко: вместо if exists(): open() используйте просто open() .
Если проверка нужна, чтобы выполнить позднее какую-либо операцию с файлом, то лучше прямо выполнить эту операцию и поймать возможные ошибки (предполагая, что вы на том же уровне ошибки хотите обработать):
#!/usr/bin/env python # -*- coding: utf-8 -*- try: file = open('input.txt') except IOError as e: print(u'не удалось открыть файл') else: with file: print(u'делаем что-то с файлом')
Предварительная проверка всё равно не гарантирует, что файл всё ещё будет существовать позднее и всё равно придётся ошибки обрабатывать.
Ответы на комментарии:
- Где блок finally в котором вы закрывается поток
finally здесь не нужен. Если код попал в except блок, то файл не открыт — нечего закрывать. В else ветке, где файл открыт, with file: конструкция всегда закрывает файл при выходе из блока (нормальном или когда исключение возникло).
- Конструкция try-exept-else многими считается плохо читаемой.
Обычно try/except не используется на том же уровне, то есть в коде используется просто:
with open('input.txt') as file: print(u'делаем что-то с файлом')
а возможные исключения выше по стеку обрабатываются. Но если вы хотите обработать ошибку в open() на том же уровне, то вы обязаны использовать try/except ( open() сигнализирует ошибки с помощью исключений).
- Каждый раз, когда файла нет, вы вызываете прерывание ОС (на нем строится механизм обработки исключения) самостоятельно, не слишком ли это раcточительно?
Исключения выбрасываются в случае ошибки в Питоне хотите вы этого или нет. Вот реализация os.path.exists() из стандартной библиотеки:
def exists(path): try: os.stat(path) except OSError: return False return True
фактически, используя open() напрямую, а не if exists(): open() мы уменьшаем количество системных вызовов.
- Ваш код занял 7 строчек, не лучше ли эту задачу поручить операционной системе командой os.path.exists(path_to_file) в пару строчек ?
Длина кода, который не работает, не имеет значения. Ещё раз: вызов os.path.exists() не гарантирует что файл существует когда вы попытаетесь вызвать open() позднее: всё равно придётся обрабатывать ошибки.
Стоит упомянуть, что если отсутствие файла не является ошибкой в вашем случае (ожидается программой), то вполне можно os.path.exists() или его аналоги использовать, чтобы подчеркнуть вероятность отсутствия файла для читателя кода (но так как последующее открытие файла может быть всё равно неудачным, то это не освобождает код от добавления обработки ошибок, подходящего для вашей задачи, такого как try/except выше).
