Berechnung der Größe eines Verzeichnisses mit Python?


181

Hat jemand eine gute Routine zum Berechnen der Größe eines Verzeichnisses mit Python, bevor ich dieses spezielle Rad neu erfinde? Es wäre sehr schön, wenn die Routine die Größe in Mb / Gb usw. gut formatieren würde.


13
Es wäre NICHT sehr schön. Sie sollten eine Funktion zum Berechnen der Größe und eine ziemlich unabhängige Funktion (die beispielsweise auch für Speichergrößen verwendet werden kann) haben, um "die Größe in MB / GB usw. gut zu formatieren".
John Machin

17
Ja, ich weiß, aber das erspart es, zwei Fragen zu stellen.
Gary Willoughby

1
Der treeBefehl auf * nix-Systemen erledigt dies alles kostenlos. tree -h -d --du /path/to/dir.
meh

@mehdu -sh /path/to/dir/*
mrgloom

Antworten:


249

Dadurch werden alle Unterverzeichnisse durchsucht. Summieren der Dateigrößen:

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')

Und ein Oneliner zum Spaß mit os.listdir (enthält keine Unterverzeichnisse ):

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

Referenz:

Aktualisiert Um os.path.getsize zu verwenden , ist dies klarer als die Verwendung der Methode os.stat (). St_size.

Vielen Dank an ghostdog74 für diesen Hinweis!

os.stat - st_size Gibt die Größe in Bytes an. Kann auch verwendet werden, um die Dateigröße und andere dateibezogene Informationen abzurufen.

import os

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

Update 2018

Wenn Sie Python 3.4 oder eine frühere Version verwenden, können Sie die effizientere walkMethode in Betracht ziehen, die vom scandirPaket eines Drittanbieters bereitgestellt wird. In Python 3.5 und höher wurde dieses Paket in die Standardbibliothek und integriertos.walk hat die entsprechende Leistungssteigerung erhalten.

Update 2019

In letzter Zeit habe ich pathlibimmer mehr verwendet, hier ist eine pathlibLösung:

from pathlib import Path

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

14
+1, aber der Oneliner gibt kein gültiges Ergebnis zurück, da es nicht rekursiv ist
luc

2
Ja, es ist nur für den Fall eines flachen Verzeichnisses.
Mönch

35
Für echten Spaß können Sie eine rekursive Größe in einer Zeile erstellen: sum (os.path.getsize (os.path.join (dirpath, Dateiname)) für dirpath, dirnames, Dateinamen in os.walk (PATH) für Dateinamen in Dateinamen)
Driax

2
Sie müssen jedoch verwenden, st_sizewenn Sie Symlinks nicht folgen möchten, wie Sie es dann verwenden sollten lstat.
Asmeurer

3
Warnung! Dies ist nicht dasselbe wie 'du -sb'. Siehe die Antwort von Samuel Lampa! Ihr Code ignoriert die Größe des Ordners, in dem FAT gespeichert ist.
Yauhen Yakimovich

43

Einige der bisher vorgeschlagenen Ansätze implementieren eine Rekursion, andere verwenden eine Shell oder führen nicht zu sauber formatierten Ergebnissen. Wenn Ihr Code für Linux-Plattformen einmalig ist, können Sie ihn wie gewohnt formatieren, einschließlich Rekursion, als Einzeiler. Mit Ausnahme von printin der letzten Zeile funktioniert es für aktuelle Versionen von python2und 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('.'))

ist einfach, effizient und funktioniert für Dateien und mehrstufige Verzeichnisse:

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

13
Nb. Nur Linux.
Meawoppl

15
Python, der plattformübergreifend in der Natur ist, sollte sich wahrscheinlich davor scheuen
Jonathan

11
Vielen Dank für diese Bemerkungen. Ich habe der Antwort einige Einschränkungen bezüglich der Plattformabhängigkeit hinzugefügt. Allerdings ein Großteil des Python-Codes bei einmaliger Skripterstellung. Solch ein Code sollte keine funktionellen Einschränkungen, langen und fehleranfälligen Passagen oder ungewöhnlichen Ergebnisse in Randfällen aufweisen, nur um eine Portabilität zu gewährleisten, die über jede Notwendigkeit hinausgeht . Es ist wie immer ein Kompromiss, und es liegt in der Verantwortung des Entwicklers, mit Bedacht zu wählen;)
flaschbier

9
Nitpick: nicht Linux, sondern Unix / Posix-spezifisch :)
Mr Shark

3
Es ist wahrscheinlich ratsam, dem Befehl du die Option '-x' hinzuzufügen, um die Suche auf das Dateisystem zu beschränken. Mit anderen Worten, verwenden Sie stattdessen ['du', '-shx', path].
Keith Hanlan

24

Hier ist eine rekursive Funktion (die die Größe aller Unterordner und ihrer jeweiligen Dateien rekursiv zusammenfasst), die genau die gleichen Bytes zurückgibt wie beim Ausführen von "du -sb". unter Linux (wobei "." "der aktuelle Ordner" bedeutet):

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("."))

2
Diese Funktion berechnet auch die Größe des Symlinks. Wenn Sie die Symlinks überspringen möchten, müssen Sie überprüfen, ob dies nicht der Fall ist: if os.path.isfile (itempath) und os.path.islink (itempath) und elif os.path.isdir ( itempath) und os.path.islink (itempath).
zwischen dem

17

Größe des rekursiven Python 3.5-Ordners mit 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

1
Python 3-Einzeilermethode, wenn Sie sich keine Gedanken über die Rekursivität machen sum([entry.stat().st_size for entry in os.scandir(file)]). Beachten Sie, dass die Ausgabe in Bytes / 1024 zum Abrufen von KB und / (1024 * 1024) zum Abrufen von MB erfolgt.
weiji14

4
@ weiji14 Verliere die Klammern, dh , sum(entry.stat().st_size for entry in os.scandir(file)). Kein Grund, eine Liste zu sumerstellen , da auch Iteratoren erforderlich sind.
Vedran Šego

8

Die Antwort von monknut ist gut, schlägt jedoch bei einem defekten Symlink fehl. Daher müssen Sie auch überprüfen, ob dieser Pfad wirklich vorhanden ist

if os.path.exists(fp):
    total_size += os.stat(fp).st_size

3
Sie möchten wahrscheinlich keinen Symlinks folgen. Sie sollten verwenden lstat.
Asmeurer

8

Die akzeptierte Antwort berücksichtigt keine harten oder weichen Links und würde diese Dateien zweimal zählen. Sie möchten verfolgen, welche Inodes Sie gesehen haben, und nicht die Größe für diese Dateien hinzufügen.

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()

5
Erwägen Sie die Verwendung os.lstat(anstelle von os.stat), wodurch folgende symbolische Links vermieden werden
Peter Briggs

7

Chris 'Antwort ist gut, könnte aber durch die Verwendung eines Sets zur Überprüfung auf gesehene Verzeichnisse idiomatischer gestaltet werden, wodurch auch die Verwendung einer Ausnahme für den Kontrollfluss vermieden wird:

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

2
Chris 'Antwort berücksichtigt auch weder Symlinks noch die Größe der Verzeichnisse selbst. Ich habe Ihre Antwort entsprechend bearbeitet, die Ausgabe der festen Funktion ist jetzt identisch mit df -sb.
Creshal

7

ein rekursiver Einzeiler:

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))])

1
Es ist jedoch kein einziger Liner. Es berechnet jedoch die rekursive Ordnergröße (auch wenn der Ordner mehrere Ordner enthält) in Bytes und gibt den korrekten Wert an.
Venkatesh

Ich ging für diese als einfach zu bedienen und arbeitete zum ersten Mal unter Windows
hum3

5

Für den zweiten Teil der Frage

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])

5

Mit habe pathlibich diesen Einzeiler gefunden, um die Größe eines Ordners zu erhalten:

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

Und das habe ich mir für eine schön formatierte Ausgabe ausgedacht:

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))   

Verwendung:

>>> 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)

Ich bin auch auf diese Frage gestoßen , die einige kompaktere und wahrscheinlich leistungsfähigere Strategien zum Drucken von Dateigrößen enthält.


4

Sie können so etwas tun:

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

In diesem Fall habe ich das Ergebnis vor der Rückgabe nicht getestet. Wenn Sie möchten, können Sie es mit command.getstatusoutput überprüfen.


Wie ist die Leistung im Vergleich zur os.walkrekursiven Überprüfung der Größe von Unterordnern?
TomSawyer


4

Ein wenig spät , um die Partei , sondern in einer Zeile , vorausgesetzt, Sie haben glob2 und humanisieren installiert. Beachten Sie, dass der Standard in Python 3 iglobeinen rekursiven Modus hat. Das Ändern des Codes für Python 3 bleibt dem Leser als triviale Übung.

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

1
Ab Python 3.5 globunterstützt das integrierte Programm die Rekursion. Sie können verwenden:glob.glob('/var/**', recursive=True)
Adzenith

3

Das folgende Skript gibt die Verzeichnisgröße aller Unterverzeichnisse für das angegebene Verzeichnis aus. Es wird auch versucht, (wenn möglich) vom Zwischenspeichern der Aufrufe einer rekursiven Funktion zu profitieren. Wenn ein Argument weggelassen wird, funktioniert das Skript im aktuellen Verzeichnis. Die Ausgabe ist nach der Verzeichnisgröße vom größten zum kleinsten sortiert. So können Sie es an Ihre Bedürfnisse anpassen.

PS Ich habe Rezept 578019 verwendet, um die Verzeichnisgröße in einem benutzerfreundlichen Format anzuzeigen ( 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())

Beispielausgabe:

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)

BEARBEITEN: null_decorator oben verschoben, wie von user2233949 empfohlen


Ihr Skript funktioniert gut, aber Sie müssen die Funktion null_decorator über die Zeile 'if sys.version_info> = ...' verschieben. Andernfalls erhalten Sie eine 'null_decorator' ist keine Ausnahme definiert. Funktioniert danach aber super.
user2233949

@ user2233949, danke! Ich habe den Code entsprechend geändert.
MaxU

3

benutze Bibliothek sh : das Modul dumacht es:

pip install sh

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

Wenn Sie Asterix übergeben möchten, verwenden Sie globwie hier beschrieben .

Verwenden Sie humanize , um die Werte in lesbare Elemente umzuwandeln :

pip install humanize

import humanize
print( humanize.naturalsize( 91157384 ) )
91.2 MB

2

Um die Größe einer Datei zu ermitteln, gibt es os.path.getsize ()

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

Es wird in Bytes angegeben.


2

Für das, was es wert ist ... macht der Befehl tree all dies kostenlos:

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

Ich liebe Python, aber die mit Abstand einfachste Lösung für das Problem erfordert keinen neuen Code.


@ Abdur-RahmaanJanhangeer, das ist wahr. Das ist wahr.
meh

2

Es ist praktisch:

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

1

Ich verwende Python 2.7.13 mit Scandir und hier ist meine rekursive Einzeilerfunktion , um die Gesamtgröße eines Ordners zu ermitteln:

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


1

Wenn die Größe der Unterverzeichnisse berechnet wird, sollte die Ordnergröße des übergeordneten Verzeichnisses aktualisiert werden. Dies wird fortgesetzt, bis das übergeordnete Stammverzeichnis erreicht ist.

Die folgende Funktion berechnet die Größe des Ordners und aller seiner Unterordner.

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

1

Wenn Sie unter Windows arbeiten, können Sie Folgendes tun:

Installieren Sie das Modul pywin32, indem Sie Folgendes starten:

pip install pywin32

und dann Codierung der folgenden:

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))

1

Hier ist ein Einzeiler, der dies rekursiv ausführt (rekursive Option ab Python 3.5 verfügbar):

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

1

für Python3.5 +

from pathlib import Path

def get_size(path):
    return sum(p.stat().st_size for p in Path(path).rglob('*'))

0

Dieses Skript zeigt Ihnen, welche Datei die größte im CWD ist und in welchem ​​Ordner sich die Datei befindet. Dieses Skript funktioniert für mich unter Win8 und 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")

0

Zugegeben, das ist etwas hackisch und funktioniert nur unter Unix / Linux.

Es stimmt überein, du -sb .da dies tatsächlich ein Python-Bash-Wrapper ist, der den du -sb .Befehl ausführt .

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])

0

Ich bin etwas spät (und neu) hier, aber ich habe mich dafür entschieden, das Unterprozessmodul und die 'du'-Befehlszeile unter Linux zu verwenden, um einen genauen Wert für die Ordnergröße in MB abzurufen. Ich musste if und elif für den Stammordner verwenden, da sonst der Unterprozess einen Fehler aufgrund eines zurückgegebenen Werts ungleich Null auslöst.

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

0

Verzeichnisgröße abrufen

Eigenschaften der Lösung:

  • Gibt sowohl die scheinbare Größe (Anzahl der Bytes in der Datei) als auch den tatsächlich von den Dateien verwendeten Speicherplatz zurück.
  • zählt fest verknüpfte Dateien nur einmal
  • zählt Symlinks genauso duwie
  • verwendet keine Rekursion
  • wird st.st_blocksfür den verwendeten Speicherplatz verwendet und funktioniert daher nur auf Unix-ähnlichen Systemen

Der 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)

Anwendungsbeispiel:

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

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

Vom Menschen lesbare Dateigröße

Eigenschaften der Lösung:

Der 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)

Anwendungsbeispiel:

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

0

Eine Lösung, die unter Python 3.6 mit pathlib funktioniert.

from pathlib import Path

sum([f.stat().st_size for f in Path("path").glob("**/*")])

0

Python 3.6+ rekursive Ordner- / Dateigröße mit os.scandir. So mächtig wie in der Antwort von @blakev, aber kürzer und im EAFP- Python-Stil .

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

0
def recursive_dir_size(path):
    size = 0

    for x in os.listdir(path):
        if not os.path.isdir(os.path.join(path,x)):
            size += os.stat(os.path.join(path,x)).st_size
        else:
            size += recursive_dir_size(os.path.join(path,x))

    return size

Ich habe diese Funktion geschrieben, die mir die genaue Gesamtgröße eines Verzeichnisses gibt. Ich habe andere for-Loop-Lösungen mit os.walk ausprobiert, aber ich weiß nicht, warum das Endergebnis immer kleiner als die tatsächliche Größe war (auf Ubuntu 18 env). Ich muss etwas falsch gemacht haben, aber wen interessiert das? Das funktioniert einwandfrei.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.