Explicação técnica
A razão pela qual a maioria dos métodos está causando problemas é que o Windows tenta enumerar os arquivos e pastas. Isso não é um grande problema com algumas centenas - ou mesmo milhares - de arquivos / pastas com alguns níveis de profundidade, mas quando você tem trilhões de arquivos em milhões de pastas com vários níveis de profundidade, então isso definitivamente vai atrapalhar o sistema.
Você tem "apenas" 100.000.000 de arquivos, e o Windows usa uma estrutura simples como essa para armazenar cada arquivo junto com seu caminho (dessa forma, você evita armazenar cada diretório separadamente, economizando um pouco de sobrecarga):
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
}
Dependendo se ele usa caracteres de 8 bits ou caracteres Unicode (ele usa Unicode) e se seu sistema é de 32 bits ou 64 bits, ele precisará de entre 25 GB e 49 GB de memória para armazenar a lista (e isso é aa estrutura muito simplificada).
O motivo pelo qual o Windows tenta enumerar os arquivos e pastas antes de excluí-los varia dependendo do método que você está usando para excluí-los, mas o Explorer e o interpretador de comandos fazem isso (você pode ver um atraso quando você inicia o comando). Você também pode ver a atividade do disco (LED do HDD) piscar enquanto lê a árvore de diretório da unidade.
Solução
Sua melhor aposta para lidar com esse tipo de situação é usar uma ferramenta de exclusão que exclua os arquivos e as pastas individualmente, um de cada vez. Não sei se existem ferramentas prontas para fazê-lo, mas deve ser possível realizar com um arquivo em lote simples.
@echo off
if not [%1]==[] cd /d %1
del /q *
for /d %%i in (*) do call %0 "%%i"
O que isto faz é verificar se um argumento foi passado. Se assim for, então ele muda para o diretório especificado (você pode executá-lo sem um argumento para iniciar no diretório atual ou especificar um diretório - mesmo em uma unidade diferente para que ele seja iniciado).
Em seguida, exclui todos os arquivos no diretório atual. Nesse modo, ele não deve enumerar nada e simplesmente excluir os arquivos sem sugar muita memória, se houver.
Em seguida, ele enumera as pastas no diretório atual e chama a si mesmo, passando cada pasta para ele (self) para recuar para baixo.
Análise
A razão pela qual isso deve funcionar é porque ele não enumera todos os arquivos e pastas na árvore inteira . Ele não enumera nenhum arquivo e apenas enumera as pastas no diretório atual (mais as restantes nos diretórios pai). Supondo que haja apenas algumas centenas de subdiretórios em uma determinada pasta, isso não deve ser tão ruim, e certamente requer muito menos memória do que outros métodos que enumeram toda a árvore.
Você pode se perguntar sobre o uso da opção /r
em vez de usar a recursão (manual). Isso não funcionaria porque, embora a opção /r
faça recursão, ela pré-enumera toda a árvore de diretórios, o que é exatamente o que queremos evitar; queremos excluir à medida que avançamos sem acompanhar.
Comparação
Vamos comparar este método com o (s) método (s) de enumeração completa.
Você disse que tinha "milhões de diretórios"; digamos 100 milhões. Se a árvore for aproximadamente balanceada e assumir uma média de cerca de 100 subdiretórios por pasta, o diretório aninhado mais profundo terá cerca de quatro níveis abaixo - na verdade, seriam 101.010.100 subpastas na árvore inteira. (Divertido como 100M pode quebrar para apenas 100 e 4).
Como não estamos enumerando arquivos, precisamos apenas controlar no máximo 100 nomes de diretório por nível, para um máximo de 4 × 100 = 400
diretórios em um dado momento.
Portanto, o requisito de memória deve ser ~ 206,25 KB, bem dentro dos limites de qualquer sistema moderno (ou qualquer outro).
Teste
Infelizmente eu não tenho um sistema com trilhões de arquivos em milhões de pastas, então eu não posso testá-lo (eu acredito na última contagem, eu tinha cerca de 800 mil arquivos), então alguém vai tem que tentar.Advertência
É claro que a memória não é a única limitação. A unidade também será um grande gargalo porque, para cada arquivo e pasta excluídos, o sistema deve marcá-lo como livre. Felizmente, muitas dessas operações de disco serão empacotadas juntas (em cache) e escritas em blocos, em vez de individualmente (pelo menos para discos rígidos, não para mídias removíveis), mas ainda causará bastante surra enquanto o sistema lê e grava os dados.