bardzo szybkie uzyskanie całkowitego rozmiaru folderu
Chcę szybko znaleźć całkowity rozmiar dowolnego folderu za pomocą Pythona.
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)
To prosty skrypt, który napisałem, aby uzyskać całkowity rozmiar folderu, zajęło to około 60 sekund (+-5 sekund). Korzystając z multiprocessingu, zmniejszyłem go do 23 sekund na czterordzeniowej maszynie.
Korzystanie z Eksploratora plików Windows zajmuje tylko ~3 sekundy (kliknij prawym przyciskiem myszy-> Właściwości, aby zobaczyć na własne oczy). Czy istnieje szybszy sposób na znalezienie całkowitego rozmiaru folderu zbliżonego do prędkości, jaką może zrobić System windows to?
Windows 7, python 2.6 (szukałem, ale większość czasu ludzie używali bardzo podobnej metody do mojego) Z góry dzięki.
3 answers
Jesteś w niekorzystnej sytuacji.
Windows Explorer prawie na pewno używa FindFirstFile
/FindNextFile
Aby zarówno przejść strukturę katalogów i zebrać informacje o rozmiarze (przez lpFindFileData
) W Jednym przejściu, co jest zasadniczo jednym wywołaniem systemowym na plik.
Python niestety nie jest twoim przyjacielem w tym przypadku. Tak więc
-
os.walk
pierwsze połączeniaos.listdir
(które wywołująFindFirstFile
/FindNextFile
)- wszelkie dodatkowe wywołania systemowe wykonywane od tego momentu mogą tylko spowolnić niż Eksplorator Windows
-
os.walk
następnie dzwoniisdir
dla każdego pliku zwracanego przezos.listdir
(który wewnętrznie wywołujeGetFileAttributesEx
-- lub, przed Win2k, aGetFileAttributes
+FindFirstFile
combo), aby ponownie określić, czy rekurencyjnie, czy nie -
os.walk
ios.listdir
wykonają dodatkową alokację pamięci , operacje na łańcuchach i tablicach itp. aby wypełnić wartość zwracaną - you then call
getsize
dla każdego pliku zwracanego przezos.walk
(który ponownie wywołujeGetFileAttributesEx
)
To 3x więcej wywołań systemowych na plik niż Windows Explorer, plus alokacja pamięci i manipulacja narzutu.
Możesz użyć rozwiązania Anurag, lub spróbować zadzwonić FindFirstFile
/FindNextFile
bezpośrednio i rekurencyjnie (co powinno być porównywalne do wydajności cygwin
lub inny Port win32 du -s some_directory
.)
Zobacz os.py
na realizacja os.walk
, posixmodule.c
do realizacji listdir
i win32_stat
(zarówno isdir
, jak i getsize
.)
Zauważ, że Python jest os.walk
jest nieoptymalna na wszystkich platformach (Windows i *nices), do Python3.1 włącznie. W obu oknach i * nices os.walk
może osiągnąć Przejście W Jednym przejściu bez wywołania isdir
, ponieważ oba FindFirst
/FindNext
(okna) oraz opendir
/readdir
(*nix) zwraca już typ pliku poprzez lpFindFileData->dwFileAttributes
(Windows) i dirent::d_type
(*nix).
GetFileAttributesEx
jest dwa razy tak wolny jak FindFirstFile
pojedynczego pliku (prawdopodobnie nawet wolniejszy niż iteracja nad katalogiem z FindNextFile
.)
Aktualizacja: Python 3.5 zawiera nowy PEP 471 os.scandir()
funkcja, która rozwiązuje ten problem zwracając atrybuty pliku wraz z nazwą pliku. Ta nowa funkcja służy do przyspieszenia wbudowanego os.walk()
(zarówno Windows jak i Linux). Możesz użyć modułu scandir na PyPI , Aby uzyskać to zachowanie dla starszych wersji Pythona, w tym 2.x.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-31 16:41:55
Jeśli chcesz mieć taką samą prędkość jak explorer, dlaczego nie użyć skryptów windows, aby uzyskać dostęp do tej samej funkcjonalności za pomocą pythoncom np.
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))
Będzie działać tak samo jak explorer, więcej o skryptach można przeczytać na stronie http://msdn.microsoft.com/en-us/library/bstcxhf7 (VS.85). aspx .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-17 13:15:40
Porównałem wydajność kodu Pythona z 15K drzewem katalogów zawierającym 190K plików i porównałem go z poleceniem du(1)
, które prawdopodobnie działa tak szybko jak system operacyjny. Kod Pythona zajął 3,3 sekundy w porównaniu do du, który zajął 0,8 sekundy. To było na Linuksie.
Nie jestem pewien, czy jest wiele do wyciśnięcia z kodu Pythona. Zauważ też, że pierwsze uruchomienie du trwało 45 sekund, co było oczywiście zanim odpowiednie i-węzły znalazły się w pamięci podręcznej bloku; dlatego to wydajność w dużym stopniu zależy od tego, jak dobrze system zarządza swoim sklepem. Nie zdziwiłoby mnie to, gdyby jedno i drugie:
- os./ align = "left" / getsize jest nieoptymalny w systemie Windows
- Windows buforuje Rozmiar zawartości katalogu po obliczeniu
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-21 03:41:47