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 até milhares - de arquivos / pastas com alguns níveis de profundidade, mas quando você tem trilhões de arquivos em milhões de pastas com dezenas de níveis de profundidade, isso definitivamente atrapalha o sistema. .
Vamos ter "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 ou 64 bits, serão necessários entre 25 GB e 49 GB de memória para armazenar a lista (e isso é muito estrutura simplificada).
O motivo pelo qual o Windows tenta enumerar os arquivos e pastas antes de excluí-los varia de acordo com o método que você está usando para excluí-los, mas o Explorer e o interpretador de comandos fazem isso (você pode ver um atraso ao iniciar o comando). Você também pode ver a atividade do disco (LED do disco rígido) piscar enquanto lê a árvore de diretórios 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 pastas individualmente, um de cada vez. Não sei se existem ferramentas prontas para fazê-lo, mas isso deve ser possível com um simples arquivo em lote.
@echo off
if not [%1]==[] cd /d %1
del /q *
for /d %%i in (*) do call %0 "%%i"
O que isso faz é verificar se um argumento foi passado. Nesse caso, 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 inicie lá).
Em seguida, ele exclui todos os arquivos no diretório atual. Nesse modo, ele não deve enumerar nada e simplesmente excluir os arquivos sem consumir muita, se houver, memória.
Em seguida, enumera as pastas no diretório atual e chama a si mesma, passando cada pasta para ele (auto) 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 existam apenas algumas centenas de subdiretórios em qualquer pasta, isso não deve ser muito ruim e certamente requer muito menos memória do que outros métodos que enumeram a árvore inteira.
Você pode se perguntar sobre o uso da /r
opção em vez de recursão (manual). Isso não funcionaria porque, embora o /r
switch faça recursão, ele pré-enumera toda a árvore de diretórios, exatamente o que queremos evitar; queremos excluir à medida que avançamos sem acompanhar.
Comparação
Vamos comparar esse 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 estiver aproximadamente equilibrada, e assumindo uma média de cerca de 100 subdiretórios por pasta, o diretório aninhado mais profundo estaria cerca de quatro níveis abaixo - na verdade, haveria 101.010.100 subpastas na árvore inteira. (Divertido como 100M pode ser dividido em apenas 100 e 4.)
Como não estamos enumerando arquivos, precisamos acompanhar apenas no máximo 100 nomes de diretório por nível, para um máximo de 4 × 100 = 400
diretórios a qualquer momento.
Portanto, o requisito de memória deve ser ~ 206,25 KB, bem dentro dos limites de qualquer sistema moderno (ou não).
Teste
Infelizmente (?) Eu não tenho um sistema com trilhões de arquivos em milhões de pastas, por isso não consigo testá-lo (acredito que na última contagem, eu tinha cerca de ~ 800K arquivos), então alguém terá que tentar isto.
Embargo
Claro que a memória não é a única limitação. A unidade também será um grande gargalo, pois para cada arquivo e pasta excluído, o sistema deve marcá-lo como livre. Felizmente, muitas dessas operações de disco serão agrupadas (armazenadas em cache) e gravadas em blocos em vez de individualmente (pelo menos para discos rígidos, não para mídia removível), mas ainda causará um grande estrago à medida que o sistema lê e escreve os dados.