Как получить размер файла в Python
Мы можем получить размер файла в Python, используя модуль os.
Размер файла в Python
Модуль python os имеет функцию stat(), где мы можем передать имя файла в качестве аргумента. Эта функция возвращает структуру кортежа, содержащую информацию о файле. Затем мы можем получить его свойство st_size , чтобы получить размер файла в байтах. Вот простая программа для печати размера файла в байтах и мегабайтах.
# get file size in python import os file_name = "/Users/pankaj/abcdef.txt" file_stats = os.stat(file_name) print(file_stats) print(f'File Size in Bytes is ') print(f'File Size in MegaBytes is ')
Если вы посмотрите на функцию stat(), мы можем передать еще два аргумента: dir_fd и follow_symlinks. Однако они не реализованы для Mac OS. Вот обновленная программа, в которой я пытаюсь использовать относительный путь, но она выдает NotImplementedError.
# get file size in python import os file_name = "abcdef.txt" relative_path = os.open("/Users/pankaj", os.O_RDONLY) file_stats = os.stat(file_name, dir_fd=relative_path)
Traceback (most recent call last): File "/Users/pankaj/. /get_file_size.py", line 7, in file_stats = os.stat(file_name, dir_fd=relative_path) NotImplementedError: dir_fd unavailable on this platform
Статья Получение размера директории с помощью Python
Эта небольшая заметка предназначена скорее для тех, кто только начинает осваивать python. Речь в ней пойдет о том, как узнать размер папки. Для тех же, кто уже давно программирует, данная информация, скорее всего, будет уже известна.
Чтобы не ходить очень далеко, возьму пример из собственного опыта. Мне потребовалось узнать размер директории. Я был немного удивлен, когда узнал, что размер нельзя получить, просто запросив os.stat(‘путь к директории’).st_size. Вернее можно, вот только возвращался стабильно одинаковый результат – 4 килобайта. Можете сами убедиться на примере. Ниже представлен небольшой скрипт, в котором, указав путь к директории (именно к директории, а не файлу), вы получите ее размер.
import os def get_size(bts, ending='B'): for item in ["", "K", "M", "G", "T", "P"]: if bts < 1024: return f"" bts /= 1024 print(get_size(os.stat(input("Введите путь к директории: ")).st_size))
Тогда я подумал, потом еще немного и попытался разобраться. Получается, что даже если вы попробуете узнать размер папки с помощью контекстного меню папки, выбрав «Свойства», результат вы получите не сразу. Пройдет некоторое время, которое будет напрямую зависеть от количества файлов, скорости жесткого диска и прочих параметров, прежде чем вы получите размер.
Подсчет размера директории в Windows
То есть, происходит считывание размера каждого файла, находящегося во всех папках, которые есть в данном расположении. Тогда я сделал небольшой скрипт, который помог на тот момент получить размер директории. Он работает как в Windows, так и в Linux и, думаю, что для большинства задач его вполне хватит.
Здесь мы создали функцию get_size, которая будет получать размер в байтах, а возвращать уже приведенное к одному из измерений размере. Ну и функция volume, в которую передается путь к директории, с помощью функции os.walk обходятся рекурсивно все директории. Затем в каждой директории, если там есть файлы, получаем их размер и суммируем в переменной size. После чего возвращаем ее из функции.
Скрипт для подсчета размера директории
import sys from os import walk from pathlib import Path def get_size(bts, ending='B'): for item in ["", "K", "M", "G", "T", "P"]: if bts < 1024: return f"" bts /= 1024 def volume(path_dir): size = 0 for path, dirs, files in walk(path_dir): for file in files: size += (Path(path) / file).stat().st_size return size def main(): path = input("Введите путь к директории: ") if not Path(path).exists() or not Path(path).is_dir() or not path: print("Указанного пути не существует или введенный путь не является директорией.") sys.exit(0) print(get_size(volume(path))) if __name__ == "__main__": main()
Если же нужно немного больше, давайте сделаем скрипт, предназначение которого и будет заключаться в том, чтобы возвращать размер директории, количество папок и файлов в ней.
Импорт библиотек
Для начала импортируем нужные для работы скрипта библиотеки. Сторонних библиотек устанавливать не требуется, поэтому пишем:
import os import sys from pathlib import Path
Создание и инициализация класса
Создадим класс Size. При инициализации класса объявим три переменных. В переменной self.volume будет храниться общий объем указанной директории. В переменной self.count_files – будем хранить количество файлов в директории, а в переменной self.count_dirs – количество папок.
class Size: def __init__(self): self.volume = 0 self.count_files = 0 self.count_dirs = 0
Создадим функцию класса get_size(bts, ending='B'), которая будет являться больше вспомогательной, поэтому, сделаем ее статической. С ней, если вы смотрели предыдущий код, вы уже должны быть знакомы. Она занимается тем, что переводит байты в большие размеры.
@staticmethod def get_size(bts, ending='B'): for item in ["", "K", "M", "G", "T", "P"]: if bts < 1024: return f"" bts /= 1024
Создадим функцию def counting(self, size). На входе она принимает размер файла и добавляет его к общему размеру self.volume. Также, здесь выводиться в терминал информация о процессе сканирования. Поэтому, если вывод данной информации не требуется, эту строку можно просто закомментировать.
def counting(self, size): self.volume += size print(f'\r total, directories and ' f'files. ', end='')
Теперь создадим функцию def size_recurse(self, path), в которую будет передаваться путь к сканируемой директории. С помощью функции os.scandir получаем информацию о файлах и папках, которые находятся в целевой директории. Данная функция используется потому, что она возвращает итератор entry_it объектов os.DirEntry. В данном случае мы немного повышаем производительность нашего скрипта, так как объекты os.DirEntry предоставляют информацию о типе или атрибуте файла, если эту информацию предоставляет операционная система, а значит, нам не нужно делать дополнительный запрос, который эту информацию бы получал. В цикле итерируемся по полученным объектам, проверяем, не является ли объект директорией. Если нет, увеличиваем счетчик файлов. Считываем размер файла и передаем в функцию counting для добавления в общий размер и вывода информации в терминал. Если же получить размер файла не удается, а такое вполне может произойти, просто продолжаем итерацию.
Если же объект является директорией, увеличиваем счетчик директорий, передаем размер объекта в функцию counting для добавления. Как вы помните, размер директории в чистом виде равен 4 килобайтам. И рекурсивно запускаем функцию size_recurse, в которую передаем директорию для сканирования. После завершения всех итераций возвращаем из класса общий объем директории в байтах. Так сделано для того, чтобы можно было использовать этот объем в чистом виде.
def size_recurse(self, path): try: for file in os.scandir(path): if not file.is_dir(follow_symlinks=False): self.count_files += 1 try: self.counting(file.stat().st_size) except: continue else: self.count_dirs += 1 self.counting(file.stat(follow_symlinks=False).st_size) self.size_recurse(file.path) return self.volume except OSError: pass
Ну и еще, сделаем наш скрипт запускаемым из командной строки. Для этого я сделал небольшой код, который получает все аргументы из командной строки. А передать в нее в качестве аргумента мы должны путь к директории, размер которой требуется узнать. Сделано это для того, чтобы, если попадется пробел в имени директории, можно было свести все аргументы вместе и передать полный путь в класс, для получения размера. Что мы и делаем. Итерируемся по всем аргументам. Я сделал их количество 100. Думаю, что вряд ли кто-то передаст в качестве параметра путь, в котором сто пробелов. И добавляем каждый найденный аргумент в список. После того, как срабатывает исключение, объединяем список, проверяем, не является ли получившийся путь пустым. Если нет, проверяем, существует ли переданный путь, является ли переданный путь директорией. И если да, передаем полученный путь в функцию класса, для получения размера. Ну, а если не выполняется какое-либо из условий, сообщаем об этом пользователю.
if __name__ == "__main__": path_arg = [] try: for i in range(1, 101): if sys.argv[i]: path_arg.append(sys.argv[i]) except IndexError: path_arg = " ".join(path_arg) if path_arg: if Path(path_arg).exists() and Path(path_arg).is_dir(): path_vol = Size().size_recurse(path_arg) print(f'\n bytes total') else: print("Директории не существует") else: print(f"Укажите путь к директории!\nПример:\n volume.py \n volume.py G:\n volume.py /home")
Вот пример работы скрипта. Попробуем узнать объем целого диска.
Python-сообщество
![]()
- Начало
- » Python для новичков
- » Размер файла?
#1 Март 25, 2012 01:10:11
PythonStriker От: Зарегистрирован: 2012-02-25 Сообщения: 33 Репутация: 0 Профиль Отправить e-mail
Размер файла?
Как узнать размер скачиваемого с url файла?
#2 Март 25, 2012 12:28:06
s0rg От: Зарегистрирован: 2011-06-05 Сообщения: 777 Репутация: 25 Профиль Отправить e-mail
Размер файла?
#3 Март 25, 2012 12:30:08
sanzstez От: Зарегистрирован: 2011-02-25 Сообщения: 8 Репутация: 0 Профиль Отправить e-mail
Размер файла?
import urllib2
req = urllib2.urlopen('http://www.google.ru/images/srpr/logo3w.png')
remote = int(req.info().getheader("Content-Length"))
print remote
#4 Март 25, 2012 13:35:54
s0rg От: Зарегистрирован: 2011-06-05 Сообщения: 777 Репутация: 25 Профиль Отправить e-mail
Размер файла?
sanzstez
Так вы отправите GET - и в результате запросите ВЕСЬ файл.
#5 Март 25, 2012 23:17:50
sanzstez От: Зарегистрирован: 2011-02-25 Сообщения: 8 Репутация: 0 Профиль Отправить e-mail
Размер файла?
ясно. ну тогда даже проще. автор не любит доки читать http://docs.python.org/library/httplib.html
и внизу примерчики
Отредактировано sanzstez (Март 25, 2012 23:18:15)
Модуль os.path

os.path является вложенным модулем в модуль os, и реализует некоторые полезные функции для работы с путями.
os.path.abspath(path) - возвращает нормализованный абсолютный путь.
os.path.basename(path) - базовое имя пути (эквивалентно os.path.split(path)[1]).
os.path.commonprefix(list) - возвращает самый длинный префикс всех путей в списке.
os.path.dirname(path) - возвращает имя директории пути path.
os.path.exists(path) - возвращает True, если path указывает на существующий путь или дескриптор открытого файла.
os.path.expanduser(path) - заменяет ~ или ~user на домашнюю директорию пользователя.
os.path.expandvars(path) - возвращает аргумент с подставленными переменными окружения ($name или $ заменяются переменной окружения name). Несуществующие имена не заменяет. На Windows также заменяет %name%.
os.path.getatime(path) - время последнего доступа к файлу, в секундах.
os.path.getmtime(path) - время последнего изменения файла, в секундах.
os.path.getctime(path) - время создания файла (Windows), время последнего изменения файла (Unix).
os.path.getsize(path) - размер файла в байтах.
os.path.isabs(path) - является ли путь абсолютным.
os.path.isfile(path) - является ли путь файлом.
os.path.isdir(path) - является ли путь директорией.
os.path.islink(path) - является ли путь символической ссылкой.
os.path.ismount(path) - является ли путь точкой монтирования.
os.path.join(path1[, path2[, . ]]) - соединяет пути с учётом особенностей операционной системы.
os.path.normcase(path) - нормализует регистр пути (на файловых системах, не учитывающих регистр, приводит путь к нижнему регистру).
os.path.normpath(path) - нормализует путь, убирая избыточные разделители и ссылки на предыдущие директории. На Windows преобразует прямые слеши в обратные.
os.path.realpath(path) - возвращает канонический путь, убирая все символические ссылки (если они поддерживаются).
os.path.relpath(path, start=None) - вычисляет путь относительно директории start (по умолчанию - относительно текущей директории).
os.path.samefile(path1, path2) - указывают ли path1 и path2 на один и тот же файл или директорию.
os.path.sameopenfile(fp1, fp2) - указывают ли дескрипторы fp1 и fp2 на один и тот же открытый файл.
os.path.split(path) - разбивает путь на кортеж (голова, хвост), где хвост - последний компонент пути, а голова - всё остальное. Хвост никогда не начинается со слеша (если путь заканчивается слешем, то хвост пустой). Если слешей в пути нет, то пустой будет голова.
os.path.splitdrive(path) - разбивает путь на пару (привод, хвост).
os.path.splitext(path) - разбивает путь на пару (root, ext), где ext начинается с точки и содержит не более одной точки.
os.path.supports_unicode_filenames - поддерживает ли файловая система Unicode.
Для вставки кода на Python в комментарий заключайте его в теги