5 способов узнать размер файла в Python: от простого к продвинутому

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Python-разработчики, желающие улучшить свои навыки работы с файлами
  • Студенты программирования, интересующиеся практическим применением Python
  • Профессионалы в области разработки, ищущие эффективные методы обработки файлов в своих проектах

    Работа с файлами — хлеб программиста. Ежедневно разработчики сталкиваются с задачами проверки, валидации и обработки файлов, где знание размера становится критически важным. Представьте: вы загружаете видеофайл на сервер с ограниченным пространством или создаете веб-приложение, требующее контроля над вложениями. В обоих случаях без точной информации о размере файла вы рискуете столкнуться с ошибками, переполнением диска или недовольством пользователей. Python предлагает целый арсенал инструментов для элегантного решения этой задачи, и я расскажу о пяти самых эффективных способах получения размера файла, которые сэкономят ваше время и нервы. 🐍📂

Если вы стремитесь овладеть не только базовыми, но и продвинутыми техниками работы с файлами в Python, обратите внимание на курс Обучение Python-разработке от Skypro. Здесь вы не только изучите все тонкости обработки данных, но и научитесь создавать полноценные веб-приложения с грамотной архитектурой. Студенты курса уже через 9 месяцев решают реальные задачи, связанные с файловыми операциями в коммерческих проектах, а трудоустройство гарантировано договором!

Что нужно знать о размере файла в Python

Прежде чем погружаться в конкретные методы, давайте разберемся с фундаментальным вопросом: что именно мы измеряем, когда говорим о "размере файла"? В Python, как и в других языках программирования, размер файла измеряется в байтах и представляет физическое пространство, занимаемое файлом на диске.

Однако важно понимать разницу между логическим и физическим размером файла:

  • Логический размер — количество данных, которые фактически содержатся в файле
  • Физический размер — пространство, занимаемое файлом на диске с учетом фрагментации, размера кластера и других особенностей файловой системы

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

Антон Петров, тимлид группы разработки

Однажды мы столкнулись с интересным кейсом: пользователи нашего сервиса жаловались на ошибки при загрузке файлов. Система показывала, что файлы превышают допустимый размер в 10 МБ, хотя пользователи утверждали, что их файлы меньше. Расследование показало, что мы использовали os.path.getsize() для проверки размера, но не учитывали, что Windows и macOS по-разному отображают размер в файловых менеджерах (используют разные множители — 1000 или 1024). После перехода на более точный метод с правильным преобразованием байтов в мегабайты проблема решилась, а количество успешных загрузок выросло на 23%.

При работе с размерами файлов в Python следует учитывать несколько ключевых моментов:

Особенность Описание На что влияет
Единицы измерения Python всегда возвращает размер в байтах Требуется дополнительное преобразование для человекочитаемого формата
Обработка ошибок Файл может не существовать или быть недоступным Необходимо обрабатывать исключения FileNotFoundError и PermissionError
Символические ссылки Разные методы по-разному обрабатывают символические ссылки Выбор метода зависит от того, нужен ли размер ссылки или целевого файла
Большие файлы Файлы >2 ГБ могут требовать особой обработки на 32-битных системах В некоторых случаях необходимо использовать 64-битные типы данных

Теперь, когда базовые концепции понятны, перейдем к конкретным методам получения размера файла, начиная с самого распространенного. 📏

Пошаговый план для смены профессии

Метод os.path.getsize(): базовый способ получения размера

Модуль os.path — ветеран Python, предоставляющий базовые инструменты для работы с файловой системой. Функция getsize() из этого модуля — самый простой и распространенный способ узнать размер файла. Ее синтаксис предельно прост:

Python
Скопировать код
import os

file_path = "example.txt"
size_in_bytes = os.path.getsize(file_path)
print(f"Размер файла: {size_in_bytes} байт")

Этот метод возвращает размер файла в байтах как целое число. Несмотря на простоту, у данного подхода есть свои особенности и ограничения:

  • Функция вызывает исключение FileNotFoundError, если файл не существует
  • Работает медленнее на больших директориях с множеством файлов, так как не кэширует результаты
  • При работе с символическими ссылками возвращает размер самой ссылки, а не целевого файла
  • Не отображает информацию о разрешениях файла или другие метаданные

Примечательно, что os.path.getsize() — кросс-платформенный метод, работающий одинаково в Windows, macOS и Linux. Это делает его идеальным выбором для базовых сценариев и скриптов, которые должны работать на разных операционных системах. 🌐

Для более надежной работы, особенно в продакшн-коде, рекомендую всегда оборачивать вызов в блок try-except:

Python
Скопировать код
import os

file_path = "example.txt"
try:
size_in_bytes = os.path.getsize(file_path)
print(f"Размер файла: {size_in_bytes} байт")
except FileNotFoundError:
print(f"Файл {file_path} не существует")
except PermissionError:
print(f"Нет разрешения на чтение файла {file_path}")

Хотя os.path.getsize() отлично подходит для простых задач, современный Python предлагает более элегантные решения, которые мы рассмотрим далее.

Объект pathlib.Path для современной работы с размером файла

С выходом Python 3.4 появилась библиотека pathlib, которая произвела революцию в работе с файловой системой, предложив объектно-ориентированный подход. Это не просто альтернатива os.path — это совершенно новый уровень элегантности и читаемости кода. 🚀

Вместо строк и множества функций из разных модулей, pathlib предлагает работать с путями как с объектами, имеющими методы и свойства:

Python
Скопировать код
from pathlib import Path

file_path = Path("example.txt")
size_in_bytes = file_path.stat().st_size
print(f"Размер файла: {size_in_bytes} байт")

Метод stat() возвращает объект, аналогичный результату os.stat(), а свойство st_size содержит размер файла в байтах. Но на этом возможности pathlib не заканчиваются:

  • Проверка существования файла: file_path.exists()
  • Определение типа файла: file_path.is_file(), file_path.is_dir()
  • Работа с разрешениями: file_path.chmod(0o755)
  • Получение информации о родительских директориях: file_path.parent

Эти дополнительные возможности делают код более выразительным и понятным. Сравните традиционный подход и pathlib:

Операция Традиционный подход Подход с pathlib
Проверка существования и получение размера
Python
Скопировать код

|

Python
Скопировать код

|

| Обработка путей |

Python
Скопировать код

|

Python
Скопировать код

|

| Объединение путей |

Python
Скопировать код

|

Python
Скопировать код

|

Мария Соколова, Python-разработчик

В нашем проекте мы обрабатывали тысячи файлов журналов ежедневно, извлекая статистику производительности. Изначально мы использовали os.path для проверки файлов перед обработкой, но код быстро стал громоздким и трудночитаемым. После рефакторинга с использованием pathlib не только уменьшилось количество строк кода на 30%, но и выросла производительность — обработка всего каталога ускорилась примерно на 15%. Самым приятным бонусом стало то, что новые разработчики теперь гораздо быстрее понимают логику кода при знакомстве с проектом. Особенно полезным оказалось комбинирование pathlib.Path.glob() с проверкой размера файлов в одном выразительном выражении.

Pathlib особенно эффективен при работе с множеством файлов. Например, чтобы найти все текстовые файлы в директории и отфильтровать их по размеру:

Python
Скопировать код
from pathlib import Path

directory = Path("my_documents")
large_text_files = [
file for file in directory.glob("*.txt") 
if file.is_file() and file.stat().st_size > 1024*1024
]
print(f"Найдено {len(large_text_files)} текстовых файлов размером более 1 МБ")

Единственным недостатком pathlib может считаться то, что в старых проектах или библиотеках все еще широко используется os.path, и смешивание подходов может привести к непоследовательному коду. Однако для новых проектов pathlib определенно стоит предпочесть.

Функции os.stat() и platform-специфичные методы измерения

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

Python
Скопировать код
import os

file_path = "example.txt"
file_stats = os.stat(file_path)
print(f"Размер файла: {file_stats.st_size} байт")
print(f"Время последнего доступа: {file_stats.st_atime}")
print(f"Время последнего изменения: {file_stats.st_mtime}")
print(f"Права доступа: {file_stats.st_mode}")

Атрибут st_size содержит размер файла в байтах, аналогично os.path.getsize(), но os.stat() предоставляет и множество другой полезной информации:

  • st_mode — права доступа к файлу
  • st_ino — индексный номер файла
  • st_dev — идентификатор устройства
  • st_uid, st_gid — идентификаторы пользователя и группы
  • st_atime — время последнего доступа
  • st_mtime — время последнего изменения
  • st_ctime — время создания (Windows) или последнего изменения статуса файла (UNIX)

Обратите внимание, что на различных платформах некоторые атрибуты могут иметь разное значение или быть недоступными. Также стоит помнить, что os.stat() следует по символическим ссылкам, если не указано иное. Если нужно получить информацию о самой ссылке, а не о файле, на который она указывает, используйте os.lstat().

Для платформенно-специфичных задач Python также предлагает особые методы:

Windows-специфичные методы

Если вы работаете в Windows и вам нужна дополнительная информация о файле, можно использовать библиотеку win32api:

Python
Скопировать код
import win32api
import win32con

file_path = "example.txt"
file_info = win32api.GetFileAttributesEx(file_path, win32con.GetFileExInfoStandard)
print(f"Размер файла: {file_info[4]} байт")
print(f"Время создания: {file_info[0]}")

Для получения физического размера файла на диске (с учетом размера кластера) можно использовать:

Python
Скопировать код
import os
import ctypes

def get_disk_usage(path):
"""Получает физический размер файла на диске в Windows."""
free_bytes = ctypes.c_ulonglong(0)
total_bytes = ctypes.c_ulonglong(0)
total_free_bytes = ctypes.c_ulonglong(0)

ctypes.windll.kernel32.GetDiskFreeSpaceExW(
ctypes.c_wchar_p(path), 
ctypes.byref(free_bytes), 
ctypes.byref(total_bytes), 
ctypes.byref(total_free_bytes)
)

# Получаем размер кластера
sectors_per_cluster = ctypes.c_ulonglong(0)
bytes_per_sector = ctypes.c_ulonglong(0)
free_clusters = ctypes.c_ulonglong(0)
total_clusters = ctypes.c_ulonglong(0)

ctypes.windll.kernel32.GetDiskFreeSpaceW(
ctypes.c_wchar_p(path),
ctypes.byref(sectors_per_cluster),
ctypes.byref(bytes_per_sector),
ctypes.byref(free_clusters),
ctypes.byref(total_clusters)
)

cluster_size = sectors_per_cluster.value * bytes_per_sector.value

# Вычисляем фактический размер файла на диске
file_size = os.path.getsize(path)
physical_size = ((file_size + cluster_size – 1) // cluster_size) * cluster_size

return physical_size

Unix-специфичные методы

В UNIX-системах (Linux, macOS) статистика файловой системы доступна через функцию statvfs:

Python
Скопировать код
import os

file_path = "example.txt"
stat_info = os.statvfs(file_path)
block_size = stat_info.f_bsize
file_size = os.path.getsize(file_path)
physical_size = ((file_size + block_size – 1) // block_size) * block_size
print(f"Логический размер: {file_size} байт")
print(f"Физический размер: {physical_size} байт")

Для сетевых файловых систем или специфических задач мониторинга можно использовать библиотеки вроде psutil:

Python
Скопировать код
import psutil

disk_usage = psutil.disk_usage('/')
print(f"Общий размер: {disk_usage.total} байт")
print(f"Используется: {disk_usage.used} байт")
print(f"Свободно: {disk_usage.free} байт")
print(f"Процент использования: {disk_usage.percent}%")

Выбор между os.stat(), pathlib.Path.stat() и платформенно-специфичными методами зависит от конкретной задачи и требуемой детализации информации. Для большинства задач достаточно универсальных методов, но если вы разрабатываете системные утилиты или нужны специфические метаданные файла, стоит обратить внимание на платформенно-ориентированные решения.

Преобразование байтов в КБ, МБ, ГБ: читаемое отображение

Размер файла в байтах не всегда удобен для восприятия человеком. Представьте себе файл размером 1073741824 байт — эта цифра мало о чем говорит, пока не преобразуешь ее в понятные 1 ГБ. Python не предоставляет встроенных функций для такого преобразования, но реализовать его достаточно просто. 🔄

Вот простая функция для преобразования байтов в человекочитаемый формат:

Python
Скопировать код
def human_readable_size(size_in_bytes, decimal_places=2):
"""Преобразует размер в байтах в человекочитаемый формат."""
for unit in ['Б', 'КБ', 'МБ', 'ГБ', 'ТБ', 'ПБ']:
if size_in_bytes < 1024.0 or unit == 'ПБ':
break
size_in_bytes /= 1024.0
return f"{size_in_bytes:.{decimal_places}f} {unit}"

file_size = 1073741824 # 1 ГБ в байтах
print(human_readable_size(file_size)) # Выведет "1.00 ГБ"

Важно отметить, что существует два стандарта для единиц измерения данных:

Система Множитель Префиксы Примечания
Двоичная (IEC) 1024 КиБ, МиБ, ГиБ, ТиБ Используется в программировании и информатике
Десятичная (SI) 1000 кБ, МБ, ГБ, ТБ Часто используется в маркетинге и документации

Путаница между этими стандартами часто приводит к недоразумениям. Например, жесткий диск, маркированный как "500 ГБ" производителем (использующим множитель 1000), будет отображаться в операционной системе как ~465 ГиБ (с множителем 1024).

Для большей точности можно модифицировать функцию, чтобы она поддерживала оба стандарта:

Python
Скопировать код
def human_readable_size(size_in_bytes, decimal_places=2, binary=True):
"""
Преобразует размер в байтах в человекочитаемый формат.

Args:
size_in_bytes: Размер в байтах
decimal_places: Количество десятичных знаков
binary: Если True, использует множитель 1024 (КиБ, МиБ),
иначе использует множитель 1000 (кБ, МБ)
"""
multiplier = 1024 if binary else 1000

if binary:
units = ['Б', 'КиБ', 'МиБ', 'ГиБ', 'ТиБ', 'ПиБ']
else:
units = ['Б', 'кБ', 'МБ', 'ГБ', 'ТБ', 'ПБ']

for unit in units:
if size_in_bytes < multiplier or unit == units[-1]:
break
size_in_bytes /= multiplier

return f"{size_in_bytes:.{decimal_places}f} {unit}"

# Примеры использования
file_size = 1500000 # примерно 1.5 МБ

# Двоичный формат (1024)
print(human_readable_size(file_size)) # "1.43 МиБ"

# Десятичный формат (1000)
print(human_readable_size(file_size, binary=False)) # "1.50 МБ"

Для практического применения рассмотрим пример скрипта, который анализирует директорию и выводит список файлов с их размерами в читаемом формате:

Python
Скопировать код
import os
from pathlib import Path

def human_readable_size(size_in_bytes, decimal_places=2):
for unit in ['Б', 'КБ', 'МБ', 'ГБ', 'ТБ']:
if size_in_bytes < 1024.0 or unit == 'ТБ':
break
size_in_bytes /= 1024.0
return f"{size_in_bytes:.{decimal_places}f} {unit}"

def analyze_directory(directory_path):
directory = Path(directory_path)
if not directory.exists() or not directory.is_dir():
print(f"Директория {directory_path} не существует или не является директорией")
return

print(f"\nАнализ директории: {directory_path}\n")
print(f"{'Файл':<40} {'Размер':<15} {'Последнее изменение'}")
print("-" * 75)

total_size = 0
file_count = 0

for file_path in directory.iterdir():
if file_path.is_file():
size = file_path.stat().st_size
total_size += size
file_count += 1

# Получаем время последнего изменения
mod_time = file_path.stat().st_mtime
time_str = time.strftime('%Y-%m-%d %H:%M', time.localtime(mod_time))

# Сокращаем слишком длинные имена файлов
file_name = file_path.name
if len(file_name) > 37:
file_name = file_name[:34] + "..."

print(f"{file_name:<40} {human_readable_size(size):<15} {time_str}")

print("-" * 75)
print(f"Всего файлов: {file_count}")
print(f"Общий размер: {human_readable_size(total_size)}")

# Пример использования
import time
analyze_directory("./documents")

Эта функциональность также легко интегрируется с другими методами получения размера файла, которые мы обсуждали ранее. Например, с pathlib:

Python
Скопировать код
from pathlib import Path

def get_file_info(file_path):
path = Path(file_path)
if not path.exists():
return None

size_in_bytes = path.stat().st_size
human_size = human_readable_size(size_in_bytes)

return {
"name": path.name,
"size_bytes": size_in_bytes,
"human_size": human_size,
"modified": path.stat().st_mtime
}

Учитывая все рассмотренные методы, вы теперь обладаете полным набором инструментов для работы с размерами файлов в Python — от получения размера в байтах до представления его в форме, понятной как программе, так и человеку. 🛠️

Мастерство работы с файлами в Python — необходимый навык для разработчика любого уровня. Представленные методы получения размера файла не просто пополнят ваш арсенал технических знаний, но и существенно упростят решение повседневных задач программирования. Помните, что выбор правильного метода зависит от конкретного сценария: от простого os.path.getsize() для быстрых проверок до продвинутых платформенно-специфичных функций для системных утилит. Независимо от сложности вашего проекта, Python предоставляет элегантные решения, которые позволяют работать с файловой системой интуитивно и эффективно.

Загрузка...