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

194

Avant de réinventer cette roue particulière, est-ce que quelqu'un a une bonne routine pour calculer la taille d'un répertoire en utilisant Python? Ce serait très bien si la routine formaterait bien la taille en Mo / Go, etc.

Gary Willoughby
la source
13
Ce ne serait PAS très agréable. Vous devriez avoir une fonction pour calculer la taille et une fonction assez indépendante (qui pourrait être utilisée aussi avec des tailles de mémoire, par exemple) pour "formater la taille bien en Mb / Gb etc".
John Machin
17
Oui je sais mais cela évite de poser deux questions.
Gary Willoughby
2
La treecommande sur les systèmes * nix fait tout cela gratuitement. tree -h -d --du /path/to/dir.
meh
@mehdu -sh /path/to/dir/*
mrgloom

Réponses:

272

Cela parcourt tous les sous-répertoires; sommation des tailles de fichier:

import os

def get_size(start_path = '.'):
    total_size = 0
    for dirpath, dirnames, filenames in os.walk(start_path):
        for f in filenames:
            fp = os.path.join(dirpath, f)
            # skip if it is symbolic link
            if not os.path.islink(fp):
                total_size += os.path.getsize(fp)

    return total_size

print(get_size(), 'bytes')

Et un oneliner pour s'amuser en utilisant os.listdir ( n'inclut pas les sous-répertoires ):

import os
sum(os.path.getsize(f) for f in os.listdir('.') if os.path.isfile(f))

Référence:

Mise à jour Pour utiliser os.path.getsize , c'est plus clair que d'utiliser la méthode os.stat (). St_size.

Merci à ghostdog74 pour l'avoir signalé!

os.stat - st_size Donne la taille en octets. Peut également être utilisé pour obtenir la taille du fichier et d'autres informations relatives au fichier.

import os

nbytes = sum(d.stat().st_size for d in os.scandir('.') if d.is_file())

Mise à jour 2018

Si vous utilisez Python 3.4 ou une version antérieure, vous pouvez envisager d'utiliser la walkméthode la plus efficace fournie par le scandirpackage tiers . Dans Python 3.5 et versions ultérieures, ce package a été incorporé dans la bibliothèque standard et os.walka reçu l'augmentation correspondante des performances.

Mise à jour 2019

Récemment, j'utilise de pathlibplus en plus, voici une pathlibsolution:

from pathlib import Path

root_directory = Path('.')
sum(f.stat().st_size for f in root_directory.glob('**/*') if f.is_file())

Monkut
la source
15
+1 mais le oneliner ne renvoie pas de résultat valide car il n'est pas récursif
luc
2
Ouais, c'est juste pour le cas de répertoire plat.
monkut
38
Pour vous amuser vraiment, vous pouvez faire une taille récursive sur une ligne: sum (os.path.getsize (os.path.join (dirpath, filename)) pour dirpath, dirnames, noms de fichiers dans os.walk (PATH) pour le nom de fichier dans les noms de fichiers)
driax
2
Mais vous devez utiliser st_sizesi vous ne voulez pas suivre les liens symboliques, comme vous devriez alors utiliser lstat.
asmeurer
3
Attention! ce n'est pas la même chose que «du -sb». Voir la réponse de Samuel Lampa! Votre code ignore la taille du dossier utilisé pour stocker FAT.
Yauhen Yakimovich
48

Certaines des approches suggérées jusqu'à présent implémentent une récursivité, d'autres utilisent un shell ou ne produiront pas de résultats parfaitement formatés. Lorsque votre code est unique pour les plates-formes Linux, vous pouvez obtenir le formatage comme d'habitude, récursivité incluse, en une seule ligne. À l'exception de la printdernière ligne, il fonctionnera pour les versions actuelles de python2et 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 à plusieurs niveaux:

$ chmod 750 du.py
$ ./du.py
2,9M
flaschbier
la source
14
Nb. Linux uniquement.
meawoppl
16
Python, étant de nature multiplateforme, devrait probablement éviter cela
Jonathan
11
Merci pour ces remarques. J'ai ajouté une mise en garde concernant la dépendance de la plate-forme à la réponse. Cependant, une grande partie du code Python est un script unique. Un tel code ne doit pas être accompagné de limitations fonctionnelles, de passages longs et sujets aux erreurs, ou de résultats inhabituels dans les cas extrêmes, juste pour une portabilité au-delà de tout besoin . C'est, comme toujours, un compromis, et il est de la responsabilité du développeur de choisir judicieusement;)
flaschbier
9
Nitpick: pas Linux mais spécifique Unix / Posix :)
Mr Shark
3
Il est probablement judicieux d'ajouter l'option '-x' à la commande du afin de limiter la recherche au système de fichiers. En d'autres termes, utilisez plutôt ['du', '-shx', path].
Keith Hanlan
24

Voici une fonction récursive (elle résume récursivement la taille de tous les sous-dossiers et de leurs fichiers respectifs) qui renvoie exactement les mêmes octets que lors de l'exécution de "du -sb". sous linux (où le "." signifie "le dossier actuel"):

import os

def getFolderSize(folder):
    total_size = os.path.getsize(folder)
    for item in os.listdir(folder):
        itempath = os.path.join(folder, item)
        if os.path.isfile(itempath):
            total_size += os.path.getsize(itempath)
        elif os.path.isdir(itempath):
            total_size += getFolderSize(itempath)
    return total_size

print "Size: " + str(getFolderSize("."))
Samuel Lampa
la source
2
Cette fonction calcule également la taille du lien symbolique - si vous voulez ignorer les liens symboliques, vous devez vérifier que ce n'est pas cela: if os.path.isfile (itempath) et os.path.islink (itempath) et elif os.path.isdir ( itempath) et os.path.islink (itempath).
airween
19

Taille du dossier récursif Python 3.5 en utilisant 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
blakev
la source
1
Méthode Python 3 one-liner si vous ne vous inquiétez pas de la récursivité sum([entry.stat().st_size for entry in os.scandir(file)]). La sortie de note est en octets, / 1024 pour obtenir Ko et / (1024 * 1024) pour obtenir Mo.
weiji14
5
@ weiji14 Perdez les crochets, c'est-à-dire sum(entry.stat().st_size for entry in os.scandir(file)). Aucune raison de faire une liste, car sumprend également des itérateurs.
Vedran Šego
9

La réponse monknut est bonne mais elle échoue sur un lien symbolique cassé, vous devez donc également vérifier si ce chemin existe vraiment

if os.path.exists(fp):
    total_size += os.stat(fp).st_size
troex
la source
3
Vous ne souhaitez probablement pas suivre les liens symboliques. Vous devriez utiliser lstat.
asmeurer
8

La réponse acceptée ne prend pas en compte les liens physiques ou logiciels et compterait ces fichiers deux fois. Vous voudrez 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()
Chris
la source
5
Pensez à utiliser os.lstat(plutôt que os.stat), ce qui évite les liens symboliques suivants: docs.python.org/2/library/os.html#os.lstat
Peter Briggs
7

La réponse de Chris est bonne mais pourrait être rendue plus idiomatique en utilisant un ensemble pour vérifier les répertoires vus, ce qui évite également d'utiliser une exception pour le flux de contrôle:

def directory_size(path):
    total_size = 0
    seen = set()

    for dirpath, dirnames, filenames in os.walk(path):
        for f in filenames:
            fp = os.path.join(dirpath, f)

            try:
                stat = os.stat(fp)
            except OSError:
                continue

            if stat.st_ino in seen:
                continue

            seen.add(stat.st_ino)

            total_size += stat.st_size

    return total_size  # size in bytes
Andrewh
la source
2
La réponse de Chris ne prend pas non plus en compte les liens symboliques ni la taille des répertoires eux-mêmes. J'ai modifié votre réponse en conséquence, la sortie de la fonction fixe est désormais identique à df -sb.
Creshal
7

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 source
1
Ce n'est cependant pas une seule doublure. Cependant, il calcule de manière récursive la taille du dossier (même si le dossier contient plusieurs dossiers) en octets et donne la valeur correcte.
Venkatesh
Je suis allé pour cela aussi facile à utiliser et j'ai travaillé pour la première fois sur Windows
hum3
7

En utilisant, pathlibj'ai monté ce one-liner pour obtenir la taille d'un dossier:

sum(file.stat().st_size for file in Path(folder).rglob('*'))

Et c'est ce que j'ai proposé pour une sortie bien formatée:

from pathlib import Path


def get_folder_size(folder):
    return ByteSize(sum(file.stat().st_size for file in Path(folder).rglob('*')))


class ByteSize(int):

    _kB = 1024
    _suffixes = 'B', 'kB', 'MB', 'GB', 'PB'

    def __new__(cls, *args, **kwargs):
        return super().__new__(cls, *args, **kwargs)

    def __init__(self, *args, **kwargs):
        self.bytes = self.B = int(self)
        self.kilobytes = self.kB = self / self._kB**1
        self.megabytes = self.MB = self / self._kB**2
        self.gigabytes = self.GB = self / self._kB**3
        self.petabytes = self.PB = self / self._kB**4
        *suffixes, last = self._suffixes
        suffix = next((
            suffix
            for suffix in suffixes
            if 1 < getattr(self, suffix) < self._kB
        ), last)
        self.readable = suffix, getattr(self, suffix)

        super().__init__()

    def __str__(self):
        return self.__format__('.2f')

    def __repr__(self):
        return '{}({})'.format(self.__class__.__name__, super().__repr__())

    def __format__(self, format_spec):
        suffix, val = self.readable
        return '{val:{fmt}} {suf}'.format(val=val, fmt=format_spec, suf=suffix)

    def __sub__(self, other):
        return self.__class__(super().__sub__(other))

    def __add__(self, other):
        return self.__class__(super().__add__(other))

    def __mul__(self, other):
        return self.__class__(super().__mul__(other))

    def __rsub__(self, other):
        return self.__class__(super().__sub__(other))

    def __radd__(self, other):
        return self.__class__(super().__add__(other))

    def __rmul__(self, other):
        return self.__class__(super().__rmul__(other))   

Usage:

>>> size = get_folder_size("c:/users/tdavis/downloads")
>>> print(size)
5.81 GB
>>> size.GB
5.810891855508089
>>> size.gigabytes
5.810891855508089
>>> size.PB
0.005674699077644618
>>> size.MB
5950.353260040283
>>> size
ByteSize(6239397620)

Je suis également tombé sur cette question , qui a des stratégies plus compactes et probablement plus performantes pour l'impression de tailles de fichiers.

Terry Davis
la source
5

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])
Aurélien Ooms
la source
4

Vous pouvez faire quelque chose comme ceci:

import commands   
size = commands.getoutput('du -sh /path/').split()[0]

dans ce cas, je n'ai pas testé le résultat avant de le renvoyer, si vous le souhaitez, vous pouvez le vérifier avec commandes.getstatusoutput.

Ali SAID OMAR
la source
Quelle est la performance par rapport à l'utilisation os.walkpour vérifier la taille du sous-dossier de manière récursive?
TomSawyer
4

Un peu tard pour le parti , mais dans une ligne à condition que vous avez glob2 et Humaniser installé. Notez que dans Python 3, la valeur par défaut igloba 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'
Sardathrion - contre les abus SE
la source
1
À partir de Python 3.5, la fonction intégrée globprend en charge la récursivité. Vous pouvez utiliser:glob.glob('/var/**', recursive=True)
adzenith
3

Le script suivant imprime la taille du répertoire de tous les sous-répertoires pour le répertoire spécifié. Il essaie également de bénéficier (si possible) de la mise en cache des appels d'une fonction récursive. Si un argument est omis, le script fonctionnera dans le répertoire courant. La sortie est triée par la taille du répertoire du plus grand au plus petit. Vous pouvez donc l'adapter à vos besoins.

PS, j'ai utilisé la recette 578019 pour afficher la taille du répertoire dans un format convivial ( http://code.activestate.com/recipes/578019/ )

from __future__ import print_function
import os
import sys
import operator

def null_decorator(ob):
    return ob

if sys.version_info >= (3,2,0):
    import functools
    my_cache_decorator = functools.lru_cache(maxsize=4096)
else:
    my_cache_decorator = null_decorator

start_dir = os.path.normpath(os.path.abspath(sys.argv[1])) if len(sys.argv) > 1 else '.'

@my_cache_decorator
def get_dir_size(start_path = '.'):
    total_size = 0
    if 'scandir' in dir(os):
        # using fast 'os.scandir' method (new in version 3.5)
        for entry in os.scandir(start_path):
            if entry.is_dir(follow_symlinks = False):
                total_size += get_dir_size(entry.path)
            elif entry.is_file(follow_symlinks = False):
                total_size += entry.stat().st_size
    else:
        # using slow, but compatible 'os.listdir' method
        for entry in os.listdir(start_path):
            full_path = os.path.abspath(os.path.join(start_path, entry))
            if os.path.isdir(full_path):
                total_size += get_dir_size(full_path)
            elif os.path.isfile(full_path):
                total_size += os.path.getsize(full_path)
    return total_size

def get_dir_size_walk(start_path = '.'):
    total_size = 0
    for dirpath, dirnames, filenames in os.walk(start_path):
        for f in filenames:
            fp = os.path.join(dirpath, f)
            total_size += os.path.getsize(fp)
    return total_size

def bytes2human(n, format='%(value).0f%(symbol)s', symbols='customary'):
    """
    (c) http://code.activestate.com/recipes/578019/

    Convert n bytes into a human readable string based on format.
    symbols can be either "customary", "customary_ext", "iec" or "iec_ext",
    see: http://goo.gl/kTQMs

      >>> bytes2human(0)
      '0.0 B'
      >>> bytes2human(0.9)
      '0.0 B'
      >>> bytes2human(1)
      '1.0 B'
      >>> bytes2human(1.9)
      '1.0 B'
      >>> bytes2human(1024)
      '1.0 K'
      >>> bytes2human(1048576)
      '1.0 M'
      >>> bytes2human(1099511627776127398123789121)
      '909.5 Y'

      >>> bytes2human(9856, symbols="customary")
      '9.6 K'
      >>> bytes2human(9856, symbols="customary_ext")
      '9.6 kilo'
      >>> bytes2human(9856, symbols="iec")
      '9.6 Ki'
      >>> bytes2human(9856, symbols="iec_ext")
      '9.6 kibi'

      >>> bytes2human(10000, "%(value).1f %(symbol)s/sec")
      '9.8 K/sec'

      >>> # precision can be adjusted by playing with %f operator
      >>> bytes2human(10000, format="%(value).5f %(symbol)s")
      '9.76562 K'
    """
    SYMBOLS = {
        'customary'     : ('B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'),
        'customary_ext' : ('byte', 'kilo', 'mega', 'giga', 'tera', 'peta', 'exa',
                           'zetta', 'iotta'),
        'iec'           : ('Bi', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi'),
        'iec_ext'       : ('byte', 'kibi', 'mebi', 'gibi', 'tebi', 'pebi', 'exbi',
                           'zebi', 'yobi'),
    }
    n = int(n)
    if n < 0:
        raise ValueError("n < 0")
    symbols = SYMBOLS[symbols]
    prefix = {}
    for i, s in enumerate(symbols[1:]):
        prefix[s] = 1 << (i+1)*10
    for symbol in reversed(symbols[1:]):
        if n >= prefix[symbol]:
            value = float(n) / prefix[symbol]
            return format % locals()
    return format % dict(symbol=symbols[0], value=n)

############################################################
###
###  main ()
###
############################################################
if __name__ == '__main__':
    dir_tree = {}
    ### version, that uses 'slow' [os.walk method]
    #get_size = get_dir_size_walk
    ### this recursive version can benefit from caching the function calls (functools.lru_cache)
    get_size = get_dir_size

    for root, dirs, files in os.walk(start_dir):
        for d in dirs:
            dir_path = os.path.join(root, d)
            if os.path.isdir(dir_path):
                dir_tree[dir_path] = get_size(dir_path)

    for d, size in sorted(dir_tree.items(), key=operator.itemgetter(1), reverse=True):
        print('%s\t%s' %(bytes2human(size, format='%(value).2f%(symbol)s'), d))

    print('-' * 80)
    if sys.version_info >= (3,2,0):
        print(get_dir_size.cache_info())

Exemple de sortie:

37.61M  .\subdir_b
2.18M   .\subdir_a
2.17M   .\subdir_a\subdir_a_2
4.41K   .\subdir_a\subdir_a_1
----------------------------------------------------------
CacheInfo(hits=2, misses=4, maxsize=4096, currsize=4)

EDIT: déplacé null_decorator ci-dessus, comme user2233949 recommandé

MaxU
la source
Votre script fonctionne bien, mais vous devez déplacer la fonction null_decorator au-dessus de la ligne 'if sys.version_info> = ...'. Sinon, vous obtiendrez une exception «null_decorator» n'est pas définie. Fonctionne très bien après cela.
user2233949
@ user2233949, merci! J'ai modifié le code en conséquence.
MaxU
3

use library sh : le module le dufait:

pip install sh

import sh
print( sh.du("-s", ".") )
91154728        .

si vous voulez passer astérix, utilisez globcomme décrit ici .

pour convertir les valeurs en lisibles par l'homme, utilisez humanize :

pip install humanize

import humanize
print( humanize.naturalsize( 91157384 ) )
91.2 MB
Chris
la source
2

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.

ghostdog74
la source
2

Pour ce que ça vaut ... la commande tree 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.

meh
la source
@ Abdur-RahmaanJanhangeer, c'est vrai. C'est vrai.
meh le
2

C'est pratique:

import os
import stat

size = 0
path_ = ""
def calculate(path=os.environ["SYSTEMROOT"]):
    global size, path_
    size = 0
    path_ = path

    for x, y, z in os.walk(path):
        for i in z:
            size += os.path.getsize(x + os.sep + i)

def cevir(x):
    global path_
    print(path_, x, "Byte")
    print(path_, x/1024, "Kilobyte")
    print(path_, x/1048576, "Megabyte")
    print(path_, x/1073741824, "Gigabyte")

calculate("C:\Users\Jundullah\Desktop")
cevir(size)

Output:
C:\Users\Jundullah\Desktop 87874712211 Byte
C:\Users\Jundullah\Desktop 85815148.64355469 Kilobyte
C:\Users\Jundullah\Desktop 83803.85609722137 Megabyte
C:\Users\Jundullah\Desktop 81.83970321994275 Gigabyte

la source
1

J'utilise python 2.7.13 avec scandir et voici ma fonction récursive à une ligne 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

Akarius
la source
1

Lorsque la taille des sous-répertoires est calculée, il doit mettre à jour la taille du dossier de son parent et cela continuera jusqu'à ce qu'il atteigne le parent racine.

La fonction suivante calcule la taille du dossier et de tous ses sous-dossiers.

import os

def folder_size(path):
    parent = {}  # path to parent path mapper
    folder_size = {}  # storing the size of directories
    folder = os.path.realpath(path)

    for root, _, filenames in os.walk(folder):
        if root == folder:
            parent[root] = -1  # the root folder will not have any parent
            folder_size[root] = 0.0  # intializing the size to 0

        elif root not in parent:
            immediate_parent_path = os.path.dirname(root)  # extract the immediate parent of the subdirectory
            parent[root] = immediate_parent_path  # store the parent of the subdirectory
            folder_size[root] = 0.0  # initialize the size to 0

        total_size = 0
        for filename in filenames:
            filepath = os.path.join(root, filename)
            total_size += os.stat(filepath).st_size  # computing the size of the files under the directory
        folder_size[root] = total_size  # store the updated size

        temp_path = root  # for subdirectories, we need to update the size of the parent till the root parent
        while parent[temp_path] != -1:
            folder_size[parent[temp_path]] += total_size
            temp_path = parent[temp_path]

    return folder_size[folder]/1000000.0
Nirvik Ghosh
la source
1

Si vous êtes sous Windows, vous pouvez faire:

installez le module pywin32 en lançant:

pip installer pywin32

puis coder ce qui suit:

import win32com.client as com

def get_folder_size(path):
   try:
       fso = com.Dispatch("Scripting.FileSystemObject")
       folder = fso.GetFolder(path)
       size = str(round(folder.Size / 1048576))
       print("Size: " + size + " MB")
   except Exception as e:
       print("Error --> " + str(e))
BR1COP
la source
1

Voici une ligne unique qui le fait de manière récursive (option récursive disponible à partir de Python 3.5):

import os
import glob
print(sum(os.path.getsize(f) for f in glob.glob('**', recursive=True) if os.path.isfile(f))/(1024*1024))
delica
la source
1

pour python3.5 +

from pathlib import Path

def get_size(path):
    return sum(p.stat().st_size for p in Path(path).rglob('*'))
Waket Zheng
la source
1
import os
def get_size(path = os.getcwd()):
    print("Calculating Size: ",path)
    total_size = 0
    #if path is directory--
    if os.path.isdir(path):
      print("Path type : Directory/Folder")
      for dirpath, dirnames, filenames in os.walk(path):
          for f in filenames:
              fp = os.path.join(dirpath, f)
              # skip if it is symbolic link
              if not os.path.islink(fp):
                  total_size += os.path.getsize(fp)
    #if path is a file---
    elif os.path.isfile(path):
      print("Path type : File")
      total_size=os.path.getsize(path)
    else:
      print("Path Type : Special File (Socket, FIFO, Device File)" )
      total_size=0
    bytesize=total_size
    print(bytesize, 'bytes')
    print(bytesize/(1024), 'kilobytes')
    print(bytesize/(1024*1024), 'megabytes')
    print(bytesize/(1024*1024*1024), 'gegabytes')
    return total_size


x=get_size("/content/examples")

Je suis sûr que cela aide! Pour les dossiers et les fichiers également!

Farhan Khan
la source
0

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

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")
user3762880
la source
0

Certes, c'est une sorte de piratage et ne fonctionne que sous Unix / Linux.

Cela correspond du -sb .car en fait, il s'agit d'un wrapper Python bash qui exécute la du -sb .commande.

import subprocess

def system_command(cmd):
    """"Function executes cmd parameter as a bash command."""
    p = subprocess.Popen(cmd,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         shell=True)
    stdout, stderr = p.communicate()
    return stdout, stderr

size = int(system_command('du -sb . ')[0].split()[0])
Alfonso
la source
0

Je suis un peu en retard (et nouveau) ici mais j'ai choisi d'utiliser le module de sous-processus et la ligne de commande 'du' avec Linux pour récupérer une valeur précise de la taille du dossier en Mo. J'ai dû utiliser if et elif pour le dossier racine car sinon le sous-processus soulève une erreur en raison d'une valeur non nulle renvoyée.

import subprocess
import os

#
# get folder size
#
def get_size(self, path):
    if os.path.exists(path) and path != '/':
        cmd = str(subprocess.check_output(['sudo', 'du', '-s', path])).\
            replace('b\'', '').replace('\'', '').split('\\t')[0]
        return float(cmd) / 1000000
    elif os.path.exists(path) and path == '/':
        cmd = str(subprocess.getoutput(['sudo du -s /'])). \
            replace('b\'', '').replace('\'', '').split('\n')
        val = cmd[len(cmd) - 1].replace('/', '').replace(' ', '')
        return float(val) / 1000000
    else: raise ValueError
Tomas Oliver Ramilison
la source
0

Obtenir la taille du répertoire

Propriétés de la solution:

  • renvoie les deux: la taille apparente (nombre d'octets dans le fichier) et l'espace disque réel utilisé par les fichiers.
  • ne compte qu'une seule fois les fichiers liés en dur
  • de la même façon de compte dune
  • n'utilise pas de récursivité
  • utilise st.st_blockspour l'espace disque utilisé, ne fonctionne donc que sur les systèmes de type Unix

Le code:

import os


def du(path):
    if os.path.islink(path):
        return (os.lstat(path).st_size, 0)
    if os.path.isfile(path):
        st = os.lstat(path)
        return (st.st_size, st.st_blocks * 512)
    apparent_total_bytes = 0
    total_bytes = 0
    have = []
    for dirpath, dirnames, filenames in os.walk(path):
        apparent_total_bytes += os.lstat(dirpath).st_size
        total_bytes += os.lstat(dirpath).st_blocks * 512
        for f in filenames:
            fp = os.path.join(dirpath, f)
            if os.path.islink(fp):
                apparent_total_bytes += os.lstat(fp).st_size
                continue
            st = os.lstat(fp)
            if st.st_ino in have:
                continue  # skip hardlinks which were already counted
            have.append(st.st_ino)
            apparent_total_bytes += st.st_size
            total_bytes += st.st_blocks * 512
        for d in dirnames:
            dp = os.path.join(dirpath, d)
            if os.path.islink(dp):
                apparent_total_bytes += os.lstat(dp).st_size
    return (apparent_total_bytes, total_bytes)

Exemple d'utilisation:

>>> du('/lib')
(236425839, 244363264)

$ du -sb /lib
236425839   /lib
$ du -sB1 /lib
244363264   /lib

Taille de fichier lisible par l'homme

Propriétés de la solution:

Le code:

def humanized_size(num, suffix='B', si=False):
    if si:
        units = ['','K','M','G','T','P','E','Z']
        last_unit = 'Y'
        div = 1000.0
    else:
        units = ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']
        last_unit = 'Yi'
        div = 1024.0
    for unit in units:
        if abs(num) < div:
            return "%3.1f%s%s" % (num, unit, suffix)
        num /= div
    return "%.1f%s%s" % (num, last_unit, suffix)

Exemple d'utilisation:

>>> humanized_size(236425839)
'225.5MiB'
>>> humanized_size(236425839, si=True)
'236.4MB'
>>> humanized_size(236425839, si=True, suffix='')
'236.4M'
Cloudomation
la source
0

Une solution qui fonctionne sur Python 3.6 en utilisant pathlib.

from pathlib import Path

sum([f.stat().st_size for f in Path("path").glob("**/*")])
Carlos A. Planchón
la source
0

Python 3.6+ taille du dossier / fichier récursif en utilisant os.scandir. Aussi puissant que dans la réponse de @blakev, mais plus court et dans le style python EAFP .

import os

def size(path, *, follow_symlinks=False):
    try:
        with os.scandir(path) as it:
            return sum(size(entry, follow_symlinks=follow_symlinks) for entry in it)
    except NotADirectoryError:
        return os.stat(path, follow_symlinks=follow_symlinks).st_size
don_vanchos
la source