Як я можу перевірити розмір файлу в Python?


757

Я пишу сценарій Python у Windows. Я хочу зробити щось на основі розміру файлу. Наприклад, якщо розмір більше 0, я надішлю комусь електронний лист, інакше продовжуйте робити інші речі.

Як перевірити розмір файлу?


2
Path('./doc.txt').stat().st_size
Борис

Дякую @Boris за сучасний відповідь Python (v3.4 +) :)
мак

Відповіді:


734

Вам потрібне st_sizeмайно об'єкта, повернутого користувачемos.stat . Ви можете отримати його за допомогою pathlib(Python 3.4+):

>>> from pathlib import Path
>>> Path('somefile.txt').stat()
os.stat_result(st_mode=33188, st_ino=6419862, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=1564, st_atime=1584299303, st_mtime=1584299400, st_ctime=1584299400)
>>> Path('somefile.txt').stat().st_size
1564

або використовуючи os.stat:

>>> import os
>>> os.stat('somefile.txt')
os.stat_result(st_mode=33188, st_ino=6419862, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=1564, st_atime=1584299303, st_mtime=1584299400, st_ctime=1584299400)
>>> os.stat('somefile.txt').st_size
1564

Вихід у байтах.


2
Якщо що-небудь, значення можна передавати у вигляді кратних розмірів блоку файлової системи (наприклад, 4096 байт). З радістю, вона наводиться як байти.
Джош

1
@josch - так, це приємно, для "розміру на диску" ви можете помножити stat_result.st_blocksна розмір блоку, але я все ще шукаю, як отримати це програмно і крос-платформу (не через tune2fsтощо)
Томаш Гандор

1097

Використання os.path.getsize:

>>> import os
>>> b = os.path.getsize("/path/isa_005.mp3")
>>> b
2071611

Вихід у байтах.


124
Примітка: реалізація os.path.getsizeпростоreturn os.stat(filename).st_size
wim

Отже, чи є хвилинна втрата продуктивності від використання os.path.getsize на відміну від os.stat (файл) .st_size?
словазвідси

5
@wordsforthewise вимірюй це! ~ 150 нс на моєму комп’ютері.
Давидм

@wordsforthewise це більше проблема, якщо ви також хочете отримати інші речі щодо файлу (час модифікації, тип файлу, наприклад) - тоді ви також можете отримати все з одного системного дзвінка через os.stat. Тоді різниця могла зіткнутися зі значною кількістю мікросекунд :-)
greggo

Якщо його викликають відразу після створення файлу, він повертає 0 @danben
alper

131

Інші відповіді працюють для реальних файлів, але якщо вам потрібно щось, що працює для "файлоподібних об'єктів", спробуйте це:

# f is a file-like object. 
f.seek(0, os.SEEK_END)
size = f.tell()

Він працює для реальних файлів і StringIO, в моїх обмежених тестах. (Python 2.7.3.) API, схожий на файл, звичайно, насправді не є строгим інтерфейсом, але документація API пропонує, що файлові об'єкти повинні підтримувати seek()та tell().

Редагувати

Ще одна відмінність між цим і в os.stat()тому, що ви можете stat()створити файл, навіть якщо у вас немає дозволу його читати. Очевидно, що підхід "шукати / говорити" не буде працювати, якщо ви не прочитали дозволу.

Редагувати 2

На пропозицію Джонатана, ось параноїчна версія. (Версія вище залишає покажчик файлу в кінці файлу, тому якщо ви намагалися прочитати з файлу, ви отримаєте нульові байти назад!)

# f is a file-like object. 
old_file_position = f.tell()
f.seek(0, os.SEEK_END)
size = f.tell()
f.seek(old_file_position, os.SEEK_SET)

8
Вам не потрібно імпортувати os, натомість пишіть, f.seek(0, 2)щоб шукати 0 байт з кінця.
cdosborn

2
І для останнього рядка, якщо osвін не використовується:f.seek(old_file_position, 0)
luckydonald

48
Якщо ви використовуєте цілі літерали замість названих змінних, ви катуєте когось, хто повинен підтримувати ваш код. Немає вагомих причин не імпортувати os.
Марк Е. Хааз

Дякую за рішення, яке я реалізував, і він працює чудово. Просто для підтвердження, sizeвихід у байтах?
Kedar.Aitawdekar

3
Мабуть, це принаймні трохи ризиковано, залежно від того, як реалізує Python #seek(): wiki.sei.cmu.edu/confluence/display/c/…
Autumnault

72
import os


def convert_bytes(num):
    """
    this function will convert bytes to MB.... GB... etc
    """
    for x in ['bytes', 'KB', 'MB', 'GB', 'TB']:
        if num < 1024.0:
            return "%3.1f %s" % (num, x)
        num /= 1024.0


def file_size(file_path):
    """
    this function will return the file size
    """
    if os.path.isfile(file_path):
        file_info = os.stat(file_path)
        return convert_bytes(file_info.st_size)


# Lets check the file size of MS Paint exe 
# or you can use any file path
file_path = r"C:\Windows\System32\mspaint.exe"
print file_size(file_path)

Результат:

6.1 MB

5
this function will convert bytes to MB.... GB... etcНеправильно. Ця функція перетворить байти в MiB, GiB тощо. Дивіться цю публікацію .
Май

2
Рядок 10 можна змінити на return f'{num:.1f} {x}'Python> = 3.5.
Метт М.

53

Використання pathlib( додано в Python 3.4 або резервний порт, доступний на PyPI ):

from pathlib import Path
file = Path() / 'doc.txt'  # or Path('./doc.txt')
size = file.stat().st_size

Це дійсно лише інтерфейс os.stat, але використання pathlibдає простий спосіб отримати доступ до інших операцій, пов'язаних з файлами.


18

Є bitshiftхитрість, яку я використовую, якщо хочу конвертувати з bytesбудь-якого іншого підрозділу. Якщо ви зробите правильний зсув, 10ви, як правило, зміщуєте його на замовлення (кілька разів).

Приклад: 5GB are 5368709120 bytes

print (5368709120 >> 10)  # 5242880 kilobytes (kB)
print (5368709120 >> 20 ) # 5120 megabytes (MB)
print (5368709120 >> 30 ) # 5 gigabytes (GB)

9
Це не відповідає на запитання. Питання полягає у пошуку розміру файлу, а не у форматуванні результату для споживання людиною.
Буде Менлі

1
Ці числа неправильні і, таким чином, заплутані. 5 Гб - 5е9 байт. Це повинно бути якимось читальним для людини наближенням? Де ви навіть використали щось подібне?
Др

1-біт => 2 ... 2-біт => 4 ... 3-біт => 8 ... 4-біт => 16 ... 5-біт => 32 ... 6-біт => 64 ... 7-біт => 128 ... 8-біт => 256 ... 9-біт => 512 ... 10-біт => 1024 ... 1024 байт - 1 кБ ... => 20 -bit => 1024 * 1024 = 1,048,576 байт, що становить 1024 кБ, і 1 МБ ... => 30 біт => 1024 * 1024 * 1024 = 1,073,741,824 байт, що становить 1048,576 кБ, і 1024 МБ, і 1 ГБ ... Ви заплуталися наукові позначення та десяткові знаки з двійковим / базовим-2 поданням, що використовується для обчислень. 5x9 = 5 x 10 ^ 9 = 5 000 000 000
Джеймс "Пухнастий" Бертон,

3
Хлопці, він нічого не плутав ... йому просто дали наближення, що видно, коли він каже "в основному". 2 ^ 10 - прибл. 10 ^ 3. Насправді, це наближення настільки часто , що у нього є ім'я : Mebi , GİBİ і Tebi є Мега, Гіга і Tera, відповідно. Що стосується того, що не відповідати на питання, @WillManley, у вас є справедлива точка! ;-p
Майк Вільямсон

9

Суворо дотримуючись питання, код Python (+ псевдо-код) буде:

import os
file_path = r"<path to your file>"
if os.stat(file_path).st_size > 0:
    <send an email to somebody>
else:
    <continue to other things>

-1
#Get file size , print it , process it...
#Os.stat will provide the file size in (.st_size) property. 
#The file size will be shown in bytes.

import os

fsize=os.stat('filepath')
print('size:' + fsize.st_size.__str__())

#check if the file size is less than 10 MB

if fsize.st_size < 10000000:
    process it ....

-1

у нас є два варіанти. Обидва включають імпорт ОС модуля

1) import os як os.stat () функція повертає об'єкт, який містить стільки заголовків, включаючи час, створений файлом, і останній час модифікації тощо. Серед них st_size () дає точний розмір файлу.

os.stat ("ім'я файлу"). st_size ()

2) import os У цьому нам потрібно надати точний шлях до файлу (абсолютний шлях), а не відносний шлях.

os.path.getsize ("шлях до файлу")

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.