Как я могу проверить размер файла в Python?


760

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

Как проверить размер файла?


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

Спасибо @Boris за современный ответ Python (v3.4 +) :)
— mab

Ответы:


737

Вам нужно 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 байт). К счастью, оно дается в байтах.
— josch

1
@josch - да, это хорошо, для «размера на диске» вы можете умножить stat_result.st_blocksна размер блока, но я все еще ищу, как получить его программно и кроссплатформенно (не через tune2fsи т. д.)
— Томас Гандор

1101

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

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

Вывод в байтах.


125
Примечание: реализация os.path.getsizeпростоreturn os.stat(filename).st_size
— Вим

Итак, есть ли потеря производительности при использовании os.path.getsize, а не os.stat (file) .st_size?
— словами

5
@wordsforthewise измерить это! ~ 150 нс в моем компьютере.
— Davidmh

@words, потому что это больше проблема, если вы также хотите получить другие сведения о файле (время изменения, тип файла и т. д.) - тогда вы можете получить все это с помощью одного системного вызова через 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 "file-like object", конечно, не совсем строгий интерфейс, но документация API предполагает, что file-like объекты должны поддерживать 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/…
— Autumnsault

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 и т. Д. Смотрите этот пост .
— Moi

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 ГБ - это 5e9 байтов. Это должно быть какое-то удобочитаемое приближение? Где бы вы использовали что-то подобное?
— Dre

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

3
Ребята, он ничего не перепутал ... ему просто дали приближение, что видно, когда он говорит "в основном". 2 ^ 10 составляет ок. 10 ^ 3. На самом деле, это приближение настолько распространено, что имеет название : Mebi , Gibi и Tebi - Mega, Giga и 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.