Автор оригинала: Tapan Pandey.
Python: Проверьте, пуст ли файл или каталог
Вступление
Python имеет набор встроенных библиотечных объектов и функций, которые помогут нам в решении этой задачи. В этом уроке мы узнаем, как проверить, пуст ли файл или каталог в Python.
Различайте файл и каталог
Когда мы хотим проверить, является ли путь пустым или нет, мы хотим знать, является ли он файлом или каталогом , поскольку это влияет на подход, который мы хотим использовать.
Допустим, у нас есть две переменные-заполнители dirpath
и file path
, идентифицирующие локальный каталог и файл:
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
, который предоставляет объектно-ориентированный интерфейс для работы с файловыми системами.
path lib
упрощает работу с файловыми системами по сравнению с 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 и Mac OS:
$ touch emptyfile
Или на окнах:
$ type nul > emptyfile
Давайте теперь определим переменные – пустой файл
и непустой файл
, указывающие на пустой файл с нулевыми байтами и непустой файл размером в один байт:
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
Кроме того, мы можем использовать модуль Python 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()
возвращает размер файла, указанного как path-like-object и намного проще в использовании, чем 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 = '/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)) #
Мы используем next()
, которая является встроенной функцией для извлечения следующего доступного элемента из ленивого итератора , возвращаемого os.scandir()
. Поскольку пустой каталог
не имеет доступных элементов – он возвращает None
, тогда как для непустого каталога
он возвращает os.DirEntry
объект.
Использование pathlib
Предпочтительным подходом к модулю os
является модуль pathlib
. Мы будем использовать pathlib.Path.iterdir()
, который не только проще, но и намного проще в использовании, чем os.listdir()
или os.scandir()
.
Он возвращает ленивый итеративный или генераторный объект , очень похожий на os.scandir ()
, который перебирает файлы в пути каталога, переданном в качестве аргумента:
from pathlib import Path print(Path(emptydirectory).iterdir()) #
Используя next()
, мы пытаемся получить следующий доступный элемент. С None
в качестве default return item, 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 работают с iterables , включая any() функцию, которая возвращает обратно True
если iterable имеет хотя бы один элемент, который может быть оценен как True
:
from pathlib import Path print(any(Path(emptydirectory).iterdir()) # False print(any(nonemptydirectory).iterdir()) # True
Вывод
В этом уроке мы рассмотрели, как различать файлы и каталоги, после чего проверили их пустоту.
Это можно сделать с помощью модулей os
или path lib
и их удобных функций и классов.