55 votes

obtenir très rapidement la taille totale du dossier

Je veux trouver rapidement la taille totale d'un dossier à l'aide de python.

import os
from os.path import join, getsize, isfile, isdir, splitext
def GetFolderSize(path):
    TotalSize = 0
    for item in os.walk(path):
        for file in item[2]:
            try:
                TotalSize = TotalSize + getsize(join(item[0], file))
            except:
                print("error with file:  " + join(item[0], file))
    return TotalSize
print(float(GetFolderSize("C:\\")) /1024 /1024 /1024)

C'est la simple script que j'ai écrit pour obtenir la taille totale du dossier, il a fallu environ 60 secondes (+-5 secondes). En utilisant le multitraitement je l'ai eu à 23 secondes sur un quad core de la machine.

À l'aide de l'explorateur de fichiers de Windows, il prend seulement environ 3 secondes (clic Droit-> propriétés pour voir par vous-même). Donc, il y a un moyen plus rapide de trouver la taille totale d'un dossier de près de la vitesse de windows qui peuvent le faire?

Windows 7, la version 2.6 de python (Fait des recherches, mais la plupart du temps, les gens ont utilisé une méthode très similaire à mon propre) Merci à l'avance.

83voto

vladr Points 34562

Vous êtes dans une situation désavantageuse.

L'Explorateur Windows presque certainement des usages FindFirstFile/FindNextFile à la fois de parcourir l'arborescence et de recueillir des informations sur la taille (par lpFindFileData) en un seul passage, en faisant ce qui est essentiellement un système d'appel par fichier.

Python n'est malheureusement pas votre ami dans ce cas. Ainsi,

  1. os.walk premiers appels os.listdir (qui appelle en interne FindFirstFile/FindNextFile)
    • aucun système supplémentaire appels effectués à partir de ce point ne peut que vous rendre plus lent que l'Explorateur Windows
  2. os.walk puis appelle isdir pour chaque fichier renvoyé par os.listdir (qui appelle en interne GetFileAttributesEx -- ou bien, avant de Win2k, un GetFileAttributes+FindFirstFile combo) afin de déterminer si les répéter ou pas
  3. os.walk et os.listdir effectuera une allocation supplémentaire de mémoire, de la chaîne et les opérations de matrice etc. pour remplir leur valeur de retour
  4. vous appelez ensuite getsize pour chaque fichier renvoyé par os.walk (ce qui à nouveau des appels GetFileAttributesEx)

Qui est 3x plus d'appels système par fichier de l'Explorateur Windows, en plus de l'allocation de la mémoire et de la manipulation de frais généraux.

Vous pouvez soit utiliser Anurag de la solution, ou essaie d'appeler, FindFirstFile/FindNextFile directement et de manière récursive (qui devrait être comparable à la performance d'un cygwin ou d'un autre port win32 du -s some_directory.)

Reportez-vous à l' os.py pour la mise en œuvre de l' os.walk, posixmodule.c pour la mise en œuvre de l' listdir et win32_stat (invoqué par les deux isdir et getsize.)

Notez que Python os.walk est sous-optimale sur toutes les plateformes (Windows et *nice), jusqu'à et y compris Python3.1. Sur Windows et *chouettes os.walk pourrait atteindre la traversée en un seul passage sans appel isdir depuis les deux FindFirst/FindNext (Windows) et opendir/readdir (*nix) déjà de retour type de fichier via lpFindFileData->dwFileAttributes (Windows) et dirent::d_type (*nix).


Mise à JOUR de noter que, contre toute attente intuitive, peut-être, sur la plupart des configurations modernes (par exemple, Win7 et NTFS, et même certains SMB implémentations) GetFileAttributesEx est deux fois plus lentement, FindFirstFile d'un seul fichier (peut-être même plus lent que de parcourir un répertoire FindNextFile.)

22voto

Anurag Uniyal Points 31931

Si vous voulez la même vitesse que l'explorateur, pourquoi ne pas utiliser le script Windows pour accéder à la même fonctionnalité en utilisant pythoncom, par exemple

 import win32com.client as com

folderPath = r"D:\Software\Downloads"
fso = com.Dispatch("Scripting.FileSystemObject")
folder = fso.GetFolder(folderPath)
MB=1024*1024.0
print  "%.2f MB"%(folder.Size/MB)
 

Il fonctionnera de la même manière que l’explorateur. Pour en savoir plus sur l’exécution de scripts, consultez http://msdn.microsoft.com/en-us/library/bstcxhf7(VS.85).aspx .

5voto

msw Points 25319

J'ai comparé les performances du code Python à l'encontre d'un 15k arborescence de répertoires contenant 190k fichiers et l'a comparé à l'encontre de l' du(1) commande qui sans doute va presque aussi vite que les OS. Le code Python a pris 3.3 secondes par rapport à l'uranium appauvri qui a eu 0,8 secondes. Ce qui était sur Linux.

Je ne suis pas sûr qu'il ya beaucoup à les presser de sortir le code Python. Il faut aussi noter que la première exécution de l'ua a pris 45 secondes, ce qui était évidemment avant les i-nœuds ont été dans le bloc de cache; par conséquent, cette performance est fortement dépendant de la façon dont le système est la gestion de son magasin. Il ne m'étonne pas si l'une ou les deux:

  1. os.chemin d'accès.getsize est sous-optimale sur Windows
  2. Windows met en cache le contenu d'un répertoire de la taille une fois calculée

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X