Единственное место, которое вы, возможно, недооцениваете, это то, что вы добавляете размеры файлов без учета размера блока.Например, в моей системе размер блока выделения составляет 4096 байт.Так что, если я 'echo 1> test.txt', этот 1-байтовый файл занимает 4096 байт.Мы можем переработать код, чтобы попытаться учесть блоки:
import math
import os
SIZE_NAMES = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
def get(fold):
total_size = 0
for dirpath, _, filenames in os.walk(fold):
for f in filenames:
fp = os.path.join(dirpath, f)
stat = os.stat(fp)
size = stat.st_blksize * math.ceil(stat.st_size / float(stat.st_blksize))
total_size += size
i = int(math.floor(math.log(total_size, 1024)))
p = math.pow(1024, i)
s = round(total_size / p, 2)
return "%s %s" % (s, SIZE_NAMES[i])
Хотя подсчет getsize()
влияет на все файлы, в процентном отношении он влияет на меньшие файлы больше.И, конечно же, узлы каталогов также занимают место.Кроме того, в этом расчете есть несколько проблем:
per = 100*float(get(fold))/float(5e+10)
Во-первых, он терпит неудачу, поскольку fold()
возвращает строку, подобную '122.23 MB'
, которая float()
не нравится.Во-вторых, в нем не учитывается единица измерения числа, которая была скорректирована в коде float()
, но здесь она не скорректирована.Наконец, он не решает проблему гигабайта и гибибайта (в комментариях, если не более). Т.е. пространство уменьшается на 1024 в коде fold()
, но здесь делится на 1000.Моя переделка:
number, unit = get(fold).split() # "2.34 MB" -> ["2.34", "MB"]
number = float(number) * 1024 ** SIZE_NAMES.index(unit) # 2.34 * 1024 ** 2
print("{0:%}".format(number / 500e9)) # percentage of 500GB