Calculer la taille d'un répertoire en utilisant Python?


10 Answers

Certaines des approches suggérées jusqu'ici implémentent une récursivité, d'autres utilisent un shell ou ne produisent pas de résultats soigneusement formatés. Lorsque votre code est unique pour les plates-formes Linux, vous pouvez obtenir le formatage habituel, récursion inclus, en tant que doublure. Sauf pour l' print dans la dernière ligne, il fonctionnera pour les versions actuelles de python2 et python3 :

du.py
-----
#!/usr/bin/python3
import subprocess

def du(path):
    """disk usage in human readable format (e.g. '2,1GB')"""
    return subprocess.check_output(['du','-sh', path]).split()[0].decode('utf-8')

if __name__ == "__main__":
    print(du('.'))

est simple, efficace et fonctionnera pour les fichiers et les répertoires multiniveaux:

$ chmod 750 du.py
$ ./du.py
2,9M

Un peu en retard après 5 ans, mais parce que c'est encore dans les hitlists des moteurs de recherche, ça pourrait être utile ...

Question

Avant de réinventer cette roue, quelqu'un a-t-il une bonne routine pour calculer la taille d'un répertoire en utilisant Python? Ce serait très bien si la routine formait bien la taille en Mb / Gb etc.




Un peu en retard à la fête mais en une ligne à condition que vous ayez glob2 et glob2 installé. Notez que dans Python 3, l' iglob par défaut a un mode récursif. Comment modifier le code pour Python 3 est laissé comme un exercice trivial pour le lecteur.

>>> import os
>>> from humanize import naturalsize
>>> from glob2 import iglob
>>> naturalsize(sum(os.path.getsize(x) for x in iglob('/var/**'))))
'546.2 MB'



pour obtenir la taille d'un fichier, il y a os.path.getsize ()

>>> import os
>>> os.path.getsize("/path/file")
35L

son rapporté en octets.




un one-liner récursif:

def getFolderSize(p):
   from functools import partial
   prepend = partial(os.path.join, p)
   return sum([(os.path.getsize(f) if os.path.isfile(f) else getFolderSize(f)) for f in map(prepend, os.listdir(p))])



La réponse acceptée ne tient pas compte des liens physiques ou matériels et comptabiliserait ces fichiers deux fois. Vous voudriez garder une trace des inodes que vous avez vus, et ne pas ajouter la taille de ces fichiers.

import os
def get_size(start_path='.'):
    total_size = 0
    seen = {}
    for dirpath, dirnames, filenames in os.walk(start_path):
        for f in filenames:
            fp = os.path.join(dirpath, f)
            try:
                stat = os.stat(fp)
            except OSError:
                continue

            try:
                seen[stat.st_ino]
            except KeyError:
                seen[stat.st_ino] = True
            else:
                continue

            total_size += stat.st_size

    return total_size

print get_size()



Taille de dossier récursive Python 3.5 avec os.scandir

def folder_size(path='.'):
    total = 0
    for entry in os.scandir(path):
        if entry.is_file():
            total += entry.stat().st_size
        elif entry.is_dir():
            total += folder_size(entry.path)
    return total



Ce script vous indique quel fichier est le plus grand dans le CWD et vous indique également dans quel dossier se trouve le fichier. Ce script fonctionne pour moi sur win8 et shell python 3.3.3

import os

folder=os.cwd()

number=0
string=""

for root, dirs, files in os.walk(folder):
    for file in files:
        pathname=os.path.join(root,file)
##        print (pathname)
##        print (os.path.getsize(pathname)/1024/1024)
        if number < os.path.getsize(pathname):
            number = os.path.getsize(pathname)
            string=pathname


##        print ()


print (string)
print ()
print (number)
print ("Number in bytes")



Pour la deuxième partie de la question

def human(size):

    B = "B"
    KB = "KB" 
    MB = "MB"
    GB = "GB"
    TB = "TB"
    UNITS = [B, KB, MB, GB, TB]
    HUMANFMT = "%f %s"
    HUMANRADIX = 1024.

    for u in UNITS[:-1]:
        if size < HUMANRADIX : return HUMANFMT % (size, u)
        size /= HUMANRADIX

    return HUMANFMT % (size,  UNITS[-1])



J'utilise python 2.7.13 avec https://pypi.python.org/pypi/scandir et voici ma fonction récursive one-liner pour obtenir la taille totale d'un dossier:

from scandir import scandir
def getTotFldrSize(path):
    return sum([s.stat(follow_symlinks=False).st_size for s in scandir(path) if s.is_file(follow_symlinks=False)]) + \
    + sum([getTotFldrSize(s.path) for s in scandir(path) if s.is_dir(follow_symlinks=False)])

>>> print getTotFldrSize('.')
1203245680

https://pypi.python.org/pypi/scandir




import os

def get_size(path):
    total_size = 0
    for dirpath, dirnames, filenames in os.walk(path):
        for f in filenames:
            if os.path.exists(fp):
                fp = os.path.join(dirpath, f)
                total_size += os.path.getsize(fp)

    return total_size   # in megabytes

Merci monkut et troex! Cela fonctionne vraiment bien!




Pour ce que ça vaut ... la commande de l'arbre fait tout cela gratuitement:

tree -h --du /path/to/dir  # files and dirs
tree -h -d --du /path/to/dir  # dirs only

J'adore Python, mais de loin la solution la plus simple au problème ne nécessite aucun nouveau code.




Related