Я пишу сценарий Python в Windows. Я хочу сделать что-то в зависимости от размера файла. Например, если размер больше 0, я отправлю электронное письмо кому-либо, в противном случае перейду к другим вещам.
Во всяком случае, значение может быть передано как кратное размеру блока файловой системы (например, 4096 байт). К счастью, оно дается в байтах.
josch
1
@josch - да, это хорошо, для «размера на диске» вы можете умножить stat_result.st_blocksна размер блока, но я все еще ищу, как получить его программно и кроссплатформенно (не через tune2fsи т. д.)
Итак, есть ли потеря производительности при использовании 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)
Вам не нужно импортировать os, вместо этого пишите, f.seek(0, 2)чтобы искать 0 байтов с конца.
cdosborn
2
И для последней строки, если osне используется:f.seek(old_file_position, 0)
luckydonald
48
Если вы используете целочисленные литералы вместо именованных переменных, вы мучаете любого, кто должен поддерживать ваш код. Там нет веских причин, чтобы не импортировать os.
Марк Э. Хааз
Спасибо за решение, я реализовал, и он работает нормально. Просто чтобы подтвердить, sizeвывод в байтах?
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.0def 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)
Есть bitshiftхитрость, которую я использую, если хочу преобразовать из bytesлюбого другого устройства. Если вы делаете правильный сдвиг, 10вы в основном сдвигаете его на порядок (кратно).
Это не отвечает на вопрос. Вопрос заключается в том, чтобы найти размер файла, а не в форматировании результата для потребления человеком.
Уилл Мэнли
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>
#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 MBif fsize.st_size <10000000:
process it ....
у нас есть два варианта Оба включают импорт модуля ОС
1) import os как функция os.stat () возвращает объект, который содержит так много заголовков, включая время создания файла, время последнего изменения и т. Д. Среди них st_size () дает точный размер файла.
os.stat ( "имя_файла"). st_size ()
2) import os Здесь мы должны указать точный путь к файлу (абсолютный путь), а не относительный путь.
Path('./doc.txt').stat().st_size
Ответы:
Вам нужно
st_size
свойство возвращаемого объектаos.stat
. Вы можете получить его, используяpathlib
(Python 3.4+):или используя
os.stat
:Вывод в байтах.
источник
stat_result.st_blocks
на размер блока, но я все еще ищу, как получить его программно и кроссплатформенно (не черезtune2fs
и т. д.)Использование
os.path.getsize
:Вывод в байтах.
источник
os.path.getsize
простоreturn os.stat(filename).st_size
os.stat
. Тогда разница может составить значительное количество микросекунд :-)Другие ответы работают для реальных файлов, но если вам нужно что-то, что работает для «файловых объектов», попробуйте это:
Это работает для реальных файлов и StringIO, в моем ограниченном тестировании. (Python 2.7.3.) API "file-like object", конечно, не совсем строгий интерфейс, но документация API предполагает, что file-like объекты должны поддерживать
seek()
иtell()
.редактировать
Еще одно различие между этим и тем
os.stat()
, что вы можетеstat()
файл, даже если у вас нет разрешения на его чтение. Очевидно, что подход поиска / сообщения не будет работать, если у вас нет разрешения на чтение.Редактировать 2
По предложению Джонатона, вот параноидальная версия. (Приведенная выше версия оставляет указатель файла в конце файла, поэтому, если вы попытаетесь прочитать файл, вы получите ноль байтов назад!)
источник
os
, вместо этого пишите,f.seek(0, 2)
чтобы искать 0 байтов с конца.os
не используется:f.seek(old_file_position, 0)
os
.size
вывод в байтах?#seek()
: wiki.sei.cmu.edu/confluence/display/c/…Результат:
источник
this function will convert bytes to MB.... GB... etc
Неправильно. Эта функция преобразует байты в MiB, GiB и т. Д. Смотрите этот пост .return f'{num:.1f} {x}'
Python> = 3.5.Использование
pathlib
( добавлено в Python 3.4 или бэкпорт доступен на PyPI ):На самом деле это всего лишь интерфейс
os.stat
, но использованиеpathlib
обеспечивает простой способ доступа к другим операциям, связанным с файлами.источник
Есть
bitshift
хитрость, которую я использую, если хочу преобразовать изbytes
любого другого устройства. Если вы делаете правильный сдвиг,10
вы в основном сдвигаете его на порядок (кратно).источник
Строго придерживаясь этого вопроса, код Python (+ псевдокод) будет:
источник
источник
у нас есть два варианта Оба включают импорт модуля ОС
1) import os как функция os.stat () возвращает объект, который содержит так много заголовков, включая время создания файла, время последнего изменения и т. Д. Среди них st_size () дает точный размер файла.
os.stat ( "имя_файла"). st_size ()
2) import os Здесь мы должны указать точный путь к файлу (абсолютный путь), а не относительный путь.
os.path.getsize ("путь к файлу")
источник