Python: os.stat ().размер st дает другое значение, чем du
Я создаю утилиту, которая будет проходить через каталоги и получать размеры дочерних каталогов и файлов для всех каталогов и хранить значение. Однако размеры вычисляются неправильно.
вот, что автоматически повторяется через все подкаталоги:class directory:
'''
Class that automatically traverses directories
and builds a tree with size info
'''
def __init__(self, path, parent=None):
if path[-1] != '/':
# Add trailing /
self.path = path + '/'
else:
self.path = path
self.size = 4096
self.parent = parent
self.children = []
self.errors = []
for i in os.listdir(self.path):
try:
self.size += os.lstat(self.path + i).st_size
if os.path.isdir(self.path + i) and not os.path.islink(self.path + i):
a = directory(self.path + i, self)
self.size += a.size
self.children.append(a)
except OSError:
self.errors.append(path + i)
у меня есть каталог видео, которые я тестирую эту программу с:
>>> a = directory('/var/media/television/The Wire')
>>> a.size
45289964053
однако, когда я пытаюсь то же самое с du, я получаю
$ du -sx /var/media/television/The Wire
44228824
в каталоги не содержат ссылок или чего-то особенного.
может кто-нибудь объяснить, почему os.stat()
дает странные показания размера?
- Linux (Fedora 13)
- Python 2.7
4 ответов
рассмотрим этот файл foo
-rw-rw-r-- 1 unutbu unutbu 25334 2010-10-31 12:55 foo
Он состоит из 25334 байт.
tune2fs говорит мне, что foo находится в файловой системе с размером блока 4096 байт:
% sudo tune2fs -l /dev/mapper/vg1-OS1
...
Block size: 4096
...
таким образом, самый маленький файл в файловой системе будет занимать 4096 байт, даже если его содержимое состоит всего из 1 байта. По мере увеличения файла пространство выделяется в 4096-байтовых блоках.
du reports
% du -B1 foo
28672 foo
обратите внимание, что 28672/4096 = 7. Это говорит о том, что Foo оккуписа 7 4096-байтовых блоков в файловой системе. Это наименьшее количество блоков, необходимых для хранения 25334 байт.
% du foo
28 foo
эта версия du
просто сообщает 28672/1024 округлено вниз.
du
дает размер на диске по умолчанию, по сравнению с фактическим размером файла, как указано в st_size
.
$ du test.txt
8 test.txt
$ du -b test.txt
6095 test.txt
>>> os.stat('test.txt').st_size
6095
Я бы написал этот код:
import os, os.path
def size_dir(d):
file_walker = (
os.path.join(root, f)
for root, _, files in os.walk(d)
for f in files
)
return sum(os.path.getsize(f) for f in file_walker)
Если вы хотите считать каталоги как 4k, то сделайте что-то вроде этого:
import os, os.path
def size_dir(d):
file_walker = (
os.path.join(root, f)
for root, _, files in os.walk(d)
for f in files
)
dir_walker = (
4096
for root, dirs, _ in os.walk(d)
for d in dirs
)
return 4096 + sum(os.path.getsize(f) for f in file_walker) + sum(size for size in dir_walker)
в linux (я использую CentOS),' du-b ' вернется в байтах и активирует --apparent-size таким образом, возвращая размер файла, а не объем дискового пространства, которое он использует. Попробуйте это и посмотрите, согласуется ли это с тем, что Python os.stat
говорит.