Spiegazione tecnica
Il motivo per cui la maggior parte dei metodi sta causando problemi è che Windows tenta di enumerare i file e le cartelle. Questo non è un grosso problema con poche centinaia - o addirittura migliaia - file / cartelle a pochi livelli di profondità, ma quando hai migliaia di miliardi di file in milioni di cartelle che scendono a dozzine di livelli, allora questo sicuramente bloccherà il sistema .
Ti permettiamo di avere "solo" 100.000.000 di file e Windows utilizza una struttura semplice come questa per memorizzare ogni file insieme al suo percorso (in questo modo eviti di memorizzare ogni directory separatamente, risparmiando così un sovraccarico):
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
}
A seconda che utilizzi caratteri a 8 bit o caratteri Unicode (utilizza Unicode) e se il tuo sistema è a 32 o 64 bit, saranno necessari tra 25 GB e 49 GB di memoria per memorizzare l'elenco (e questo è molto struttura semplificata).
Il motivo per cui Windows tenta di enumerare i file e le cartelle prima di eliminarli varia in base al metodo utilizzato per eliminarli, ma sia Explorer che l'interprete dei comandi lo fanno (è possibile vedere un ritardo all'avvio del comando). Puoi anche vedere l'attività del disco (LED HDD) lampeggiare mentre legge l'albero delle directory dall'unità.
Soluzione
La soluzione migliore per affrontare questo tipo di situazione è utilizzare uno strumento di eliminazione che elimina i file e le cartelle singolarmente, uno alla volta. Non so se ci sono strumenti già pronti per farlo, ma dovrebbe essere possibile farlo con un semplice file batch.
@echo off
if not [%1]==[] cd /d %1
del /q *
for /d %%i in (*) do call %0 "%%i"
Ciò che fa è verificare se è stato passato un argomento. In tal caso, passa alla directory specificata (è possibile eseguirlo senza un argomento per avviarlo nella directory corrente o specificare una directory, anche su un'unità diversa per avviarla da lì).
Successivamente, elimina tutti i file nella directory corrente. In questa modalità, non dovrebbe enumerare nulla ed eliminare semplicemente i file senza risucchiare molta memoria.
Quindi enumera le cartelle nella directory corrente e chiama se stessa, passando ciascuna cartella (auto) per ricorrere verso il basso.
Analisi
Il motivo per cui questo dovrebbe funzionare è perché non elenca tutti i singoli file e cartelle nell'intero albero . Non enumera alcun file e elenca solo le cartelle nella directory corrente (oltre a quelle rimanenti nelle directory principali). Supponendo che ci siano solo poche centinaia di sottodirectory in una determinata cartella, quindi questo non dovrebbe essere troppo male e certamente richiede molta meno memoria rispetto ad altri metodi che enumerano l'intero albero.
Potresti chiederti di usare l' /r
opzione invece di usare la ricorsione (manuale). Ciò non funzionerebbe perché mentre lo /r
switch esegue la ricorsione, pre-enumera l'intero albero di directory che è esattamente ciò che vogliamo evitare; vogliamo eliminare mentre andiamo senza tenere traccia.
Confronto
Consente di confrontare questo metodo con i metodi di enumerazione completa.
Avevi detto di avere "milioni di directory"; diciamo 100 milioni. Se l'albero è approssimativamente bilanciato e supponendo una media di circa 100 sottodirectory per cartella, la directory nidificata più profonda sarebbe di circa quattro livelli in basso, in realtà ci sarebbero 101.010.100 sottocartelle nell'intero albero. (Divertente come 100M possono essere suddivisi in soli 100 e 4.)
Poiché non stiamo enumerando i file, dobbiamo solo tenere traccia di un massimo di 100 nomi di directory per livello, per un massimo di 4 × 100 = 400
directory in qualsiasi momento.
Pertanto, il requisito di memoria dovrebbe essere ~ 206,25 KB, ben entro i limiti di qualsiasi sistema moderno (o altrimenti).
Test
Sfortunatamente (?) Non ho un sistema con trilioni di file in milioni di cartelle, quindi non sono in grado di testarlo (credo all'ultimo conteggio, avevo circa ~ 800K file), quindi qualcun altro dovrà provare esso.
Avvertimento
Naturalmente la memoria non è l'unica limitazione. L'unità sarà anche un grosso collo di bottiglia perché per ogni file e cartella che elimini, il sistema deve contrassegnarlo come libero. Per fortuna, molte di queste operazioni su disco verranno raggruppate insieme (memorizzate nella cache) e scritte in blocchi anziché singolarmente (almeno per i dischi rigidi, non per i supporti rimovibili), ma causerà comunque un bel po 'di thrashing mentre il sistema legge e scrive i dati.