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

Введение Python имеет набор встроенных библиотечных объектов и функций, которые помогают нам в решении этой задачи. В этом руководстве мы узнаем, как проверить, пуст ли файл или каталог в Python. Различие между файлом и каталогом Когда мы хотим проверить, является ли путь пустым, мы захотим узнать, является ли он файлом или каталогом, поскольку это влияет на подход, который мы хотим использовать. Допустим, у нас есть две переменные-заполнители dirpath и filepath, идентифицирующие локальный каталог и файл: dirpath =

Вступление

Python имеет набор встроенных библиотечных объектов и функций, которые помогают нам в решении этой задачи. В этом руководстве мы узнаем, как проверить, пуст ли файл или каталог в Python.

Различать файл и каталог

Когда мы хотим проверить, пуст ли путь или нет, мы захотим узнать, является ли он файлом или каталогом, поскольку это влияет на подход, который мы хотим использовать.

Допустим, у нас есть две переменные-заполнители dirpath и filepath идентифицирующие локальный каталог и файл:

 dirpath = '/mnt/f/code.books/articles/python' 
 filepath = '/mnt/f/code.books/articles/python/code/file_dir.py' 

Использование os.path

Python предоставляет os который представляет собой стандартный пакет функций, объектов и констант Python для работы с операционной системой.

os.path предоставляет нам функции isfile() и isdir() чтобы легко различать файл и каталог:

 import os 
 
 dirpath = '/mnt/f/code.books/articles/python' 
 filepath = '/mnt/f/code.books/articles/python/code/file_dir.py' 
 
 os.path.isfile(dirpath) # False 
 os.path.isdir(dirpath) # True 
 os.path.isfile(filepath) # True 
 os.path.isdir(filepath) # False 

Обе эти функции возвращают Boolean значение.

Использование pathlib

Python 3.4 представил pathlib , который предоставляет объектно-ориентированный интерфейс для работы с файловыми системами.

pathlib упрощает работу с файловыми системами по сравнению с os или os.path .

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

 from pathlib import Path 
 
 dirpath = '/mnt/f/code.books/articles/python' 
 filepath = '/mnt/f/code.books/articles/python/code/file_dir.py' 
 
 Path(dirpath).is_file() # False 
 Path(dirpath).is_dir() # True 
 Path(filepath).is_file() # True 
 Path(dirpath).is_file() # False 

Здесь мы проверяем, является ли Path файлом или каталогом.

Проверьте, пуст ли файл

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

В Linux и MacOS можно быстро создать пустой файл:

 $ touch emptyfile 

Или в Windows:

 $ type nul > emptyfile 

Давайте теперь определим переменные - emptyfile и emptyfile указывающие на пустой файл с нулевым nonemptyfile

 emptyfile = '/mnt/f/code.books/articles/python/emptyfile' 
 nonemptyfile = '/mnt/f/code.books/articles/python/onebytefile' 

Давайте посмотрим на тип и размер этих файлов:

 $ ls -l 
 -rwxrwxrwx 1 root root 0 Sep 10 18:06 emptyfile 
 -rwxrwxrwx 1 root root 1 Sep 10 18:08 onebytefile 
 $ file emptyfile 
 emptyfile: empty 
 $ file onebytefile 
 onebytefile: very short file (no magic) 

Использование os.stat

В качестве альтернативы мы можем использовать os чтобы проверить эту информацию. Функция os.stat() возвращает объект stat_result Этот объект в основном представляет собой структуру данных, которая представляет собой набор свойств файла:

 import os 
 
 emptyfile = '/mnt/f/code.books/articles/python/emptyfile' 
 nonemptyfile = '/mnt/f/code.books/articles/python/onebytefile' 
 
 result = os.stat(nonemptyfile) 
 result.st_size # 1 
 
 result = os.stat(emptyfile) 
 result.st_size # 0 

Использование os.path

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

os.path.getsize() возвращает размер файла, указанного как объект, подобный пути, и его намного проще использовать, чем os.stat() :

 import os 
 
 emptyfile = '/mnt/f/code.books/articles/python/emptyfile' 
 nonemptyfile = '/mnt/f/code.books/articles/python/onebytefile' 
 
 os.path.getsize(emptyfile) # 0 
 
 os.path.getsize(nonemptyfile) # 1 

Использование pathlib

Если мы работаем над Python 3.4 или выше, мы можем использовать pathlib для получения размера файла. Это в основном заменяет модуль os Path.stat() возвращает свойство stat_result Path которое эквивалентно возвращаемому значению os.stat() :

 from pathlib import Path 
 
 emptyfile = '/mnt/f/code.books/articles/python/emptyfile' 
 nonemptyfile = '/mnt/f/code.books/articles/python/onebytefile' 
 
 print('File stats: ' + Path(emptyfile).stat()) 
 
 print('File size: ' + Path(emptyfile).stat().st_size + ' byte(s)') 
 
 print('File stats: ' + Path(nonemptyfile).stat()) 
 
 print('File size: ' + Path(nonemptyfile).stat().st_size + ' byte(s)') 

Это приводит к:

 File stats: os.stat_result(st_mode=33279, st_ino=14355223812249048, st_dev=17, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1600087010, st_mtime=1600087010, st_ctime=1600087010) 
 File size: 0 byte(s) 
 
 File stats: os.stat_result(st_mode=33279, st_ino=5629499534218713, st_dev=17, st_nlink=1, st_uid=0, st_gid=0, st_size=1, st_atime=1600088120, st_mtime=1600088072, st_ctime=1600088072) 
 File size: 1 byte(s) 

Проверьте, пуст ли каталог

Каталог, в котором нет других файлов или подкаталогов, является пустым каталогом. Однако каждый каталог (даже пустой) содержит следующие 2 записи:

  • . ( произносится как точка ) ссылается на текущий каталог и полезен при таких операциях, как поиск чего-либо внутри текущего каталога
  • .. ( произносится как двойная точка ) ссылается на родительский каталог текущего каталога, требуется для возврата из текущего каталога

Давайте определим две переменные - emptydirectory и nonemptydirectory указывая на пустой и непустой каталог:

 emptydirectory = '/mnt/f/code.books/articles/python/markdown' 
 nonemptydirectory = '/mnt/f/code.books/articles/python/code' 

В пустом каталоге нет никаких элементов:

 $ pwd 
 /mnt/f/code.books/articles/python/markdown 
 $ ls -la 
 total 0 
 drwxrwxrwx 1 root root 512 Sep 11 11:52 . 
 drwxrwxrwx 1 root root 512 Sep 10 20:22 .. 

Непустой каталог содержит единственный файл:

 $ pwd 
 /mnt/f/code.books/articles/python/code 
 $ ls -la 
 total 0 
 drwxrwxrwx 1 root root 512 Sep 14 11:02 . 
 drwxrwxrwx 1 root root 512 Sep 14 18:22 .. 
 -rwxrwxrwx 1 root root 425 Sep 14 12:27 file_dir.py 

Использование os.listdir ()

os.listdir() возвращает последовательность, содержащую имена всех элементов, найденных в пути к каталогу, переданном в качестве аргумента. Он не включает . и .. записи:

 import os 
 
 os.listdir(emptydirectory) # [] 
 os.listdir(nonemptydirectory) # ['file_dir.py'] 

Расчет длины возвращенного списка легко определяет, пуст каталог или нет. Пустой каталог всегда имеет нулевую длину:

 import os 
 
 print(len(os.listdir(nonemptydirectory))) # 1 
 print(len(os.listdir(emptydirectory))) # 0 

Использование os.scandir ()

Функция os.listdir() полезна, когда вам нужна целая группа имен записей в виде списка для дальнейшей обработки. Однако, чтобы проверить, есть ли хотя бы одна запись, нам не нужен список всех файлов внутри.

Если каталог огромен, выполнение функции os.listdir() займет много времени, в то время как, если 0 на наш вопрос будет дан ответ.

На помощь приходит os.scandir() которая возвращает ленивую итерацию или генератор.

Генераторы возвращают итераторы, которые можно перебирать, как обычные итерации, такие как список. Но в отличие от списка, набора или словаря, они не хранят в памяти целую группу значений, а вместо этого возвращают новое значение по запросу.

Этот подход примерно в ~ 200 раз быстрее для каталогов из ~ 1000 файлов.

Поэтому вместо того, чтобы перебирать всю структуру каталогов, мы можем использовать os.scandir() чтобы проверить, есть ли хотя бы одна запись в пути к каталогу:

 import os 
 
 emptydirectory = '/mnt/f/code.books/articles/python/markdown' 
 nonemptydirectory = '/mnt/f/code.books/articles/python/code' 
 
 print(next(os.scandir(emptydirectory), None)) 
 print(next(os.scandir(nonemptydirectory), None)) # <DirEntry 'file_dir.py'> 

Мы используем next() который является встроенной функцией для получения следующего доступного элемента из ленивого итератора, возвращаемого os.scandir() . Так как emptydirectory не имеет доступных элементов - оно не возвращается None , тогда как для nonemptydirectory она возвращается в os.DirEntry объект.

Использование pathlib

Предпочтительный подход к os - это модуль pathlib Мы будем использовать pathlib.Path.iterdir() , который не только проще, но и намного проще в использовании, чем os.listdir() или os.scandir() .

Он возвращает ленивый объект-генератор или объект-генератор, очень похожий на os.scandir() , который выполняет итерацию по файлам в пути к каталогу, переданному в качестве аргумента:

 from pathlib import Path 
 print(Path(emptydirectory).iterdir()) # <generator object Path.iterdir at 0x7f2cf6f584a0> 

Используя next() , мы пытаемся получить следующий доступный элемент. Если None в качестве возвращаемого элемента по умолчанию next() не StopIteration если в коллекции нет элемента:

 print(next(Path(emptydirectory).iterdir(), None)) # None 
 print(next(Path(nonemptydirectory).iterdir(), None)) # /mnt/f/code.books/articles/python/code/file_dir.py 

Большинство встроенных функций Python работают с итерациями , включая функцию any (), которая возвращает True если итерируемый объект имеет хотя бы один элемент, который может быть оценен как True :

 from pathlib import Path 
 print(any(Path(emptydirectory).iterdir()) # False 
 print(any(nonemptydirectory).iterdir()) # True 

Заключение

В этом руководстве мы рассмотрели, как различать файлы и каталоги, после чего проверили их пустоту.

Это можно сделать с помощью os или pathlib и их вспомогательных функций и классов.

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus