Wyjaśnienie techniczne
Przyczyną problemów jest większość metod, ponieważ system Windows próbuje wyliczyć pliki i foldery. Nie stanowi to większego problemu w przypadku kilkuset - a nawet tysięcy - plików / folderów o głębokości kilku poziomów, ale jeśli masz biliony plików w milionach folderów sięgających dziesiątek poziomów, to z pewnością zapełni system. .
Załóżmy, że masz „tylko” 100 000 000 plików, a system Windows używa takiej prostej struktury do przechowywania każdego pliku wraz z jego ścieżką (w ten sposób unikniesz przechowywania każdego katalogu osobno, oszczędzając w ten sposób pewien narzut):
struct FILELIST { // Total size is 264 to 528 bytes:
TCHAR name[MAX_PATH]; // MAX_PATH=260; TCHAR=1 or 2 bytes
FILELIST* nextfile; // Pointers are 4 bytes for 32-bit and 8 for 64-bit
}
W zależności od tego, czy używa znaków 8-bitowych, czy znaków Unicode (używa Unicode) i czy twój system jest 32-bitowy czy 64-bitowy, wtedy będzie potrzebował od 25 GB do 49 GB pamięci do przechowywania listy (i jest to bardzo uproszczona struktura).
Powód, dla którego system Windows próbuje wyliczyć pliki i foldery przed ich usunięciem, różni się w zależności od metody, której używasz do ich usunięcia, ale robią to zarówno Eksplorator, jak i interpreter poleceń (możesz zauważyć opóźnienie po zainicjowaniu polecenia). Możesz także zobaczyć miganie aktywności dysku (dioda LED dysku twardego) podczas odczytywania drzewa katalogów z napędu.
Rozwiązanie
Najlepszym rozwiązaniem tego problemu jest skorzystanie z narzędzia do usuwania, które usuwa pliki i foldery pojedynczo, pojedynczo. Nie wiem, czy są na to gotowe narzędzia, ale to powinno być możliwe za pomocą prostego pliku wsadowego.
@echo off
if not [%1]==[] cd /d %1
del /q *
for /d %%i in (*) do call %0 "%%i"
Spowoduje to sprawdzenie, czy argument został przekazany. Jeśli tak, to zmienia się na podany katalog (można go uruchomić bez argumentu, aby uruchomić w bieżącym katalogu lub podać katalog - nawet na innym dysku, aby miał się tam uruchomić).
Następnie usuwa wszystkie pliki w bieżącym katalogu. W tym trybie nie powinien niczego wyliczać i po prostu usuwać pliki bez zużywania dużej, jeśli w ogóle, pamięci.
Następnie wylicza foldery w bieżącym katalogu i wywołuje się, przekazując każdy folder do siebie (siebie), aby powrócić w dół.
Analiza
Powodem tego powinno być to, że nie wylicza każdego pojedynczego pliku i folderu w całym drzewie . W ogóle nie wylicza żadnych plików i tylko wylicza foldery w bieżącym katalogu (plus pozostałe w katalogach nadrzędnych). Zakładając, że w danym folderze znajduje się tylko kilkaset podkatalogów, nie powinno to być takie złe i na pewno wymaga znacznie mniej pamięci niż inne metody, które wyliczają całe drzewo.
Możesz zastanawiać się nad użyciem /r
przełącznika zamiast (ręcznej) rekurencji. To nie zadziałałoby, ponieważ podczas gdy /r
przełącznik wykonuje rekurencję, wstępnie wylicza całe drzewo katalogów, czego dokładnie chcemy uniknąć; chcemy je usuwać bez przechodzenia.
Porównanie
Porównajmy tę metodę z metodą (metodami) pełnego wyliczania.
Powiedziałeś, że masz „miliony katalogów”; powiedzmy 100 milionów. Jeśli drzewo jest w przybliżeniu zrównoważone i zakłada średnio około 100 podkatalogów na folder, to najgłębiej zagnieżdżony katalog byłby o około cztery poziomy niżej - w rzeczywistości w całym drzewie byłoby 101 010 100 podfolderów. (Zabawne, jak 100M może rozbić się do 100 i 4).
Ponieważ nie wyliczamy plików, musimy śledzić maksymalnie 100 nazw katalogów na poziom, dla maksymalnie 4 × 100 = 400
katalogów w danym momencie.
Dlatego zapotrzebowanie na pamięć powinno wynosić ~ 206,25 KB, a więc w granicach dowolnego nowoczesnego (lub innego) systemu.
Test
Niestety (?) Nie mam systemu z bilionami plików w milionach folderów, więc nie jestem w stanie go przetestować (wydaje mi się, że na koniec liczyłem około 800 tysięcy plików), więc ktoś inny będzie musiał spróbować to.
Zastrzeżenie
Oczywiście pamięć nie jest jedynym ograniczeniem. Dysk będzie również dużym wąskim gardłem, ponieważ dla każdego usuwanego pliku i folderu system musi oznaczyć go jako wolny. Na szczęście wiele z tych operacji na dyskach zostanie połączonych razem (w pamięci podręcznej) i zapisanych we fragmentach zamiast osobno (przynajmniej dla dysków twardych, a nie dla nośników wymiennych), ale nadal będzie powodowało sporo wstrząsów podczas odczytywania systemu i zapisuje dane.