De alguma forma, uma de nossas caixas antigas do Server 2008 (não R2) desenvolveu uma pasta aparentemente infinitamente recorrente. Isso está causando estragos em nossos backups, pois o agente de backup tenta recursivamente para a pasta e nunca retorna.
A estrutura da pasta se parece com:
C:\Storage\Folder1
C:\Storage\Folder1\Folder1
C:\Storage\Folder1\Folder1\Folder1
C:\Storage\Folder1\Folder1\Folder1\Folder1
... e assim por diante. É como um daqueles conjuntos de Mandelbrot com os quais costumávamos brincar nos anos 90.
Eu tentei:
- Excluindo-o do Explorer. Sim, sou otimista.
RMDIR C:\Storage\Folder1 /Q/S
- isso retornaThe directory is not empty
ROBOCOPY C:\temp\EmptyDirectory C:\Storage\Folder1 /PURGE
- isso gira pelas pastas por alguns minutos antes que o robocopy.exe trave.
Alguém pode sugerir uma maneira de eliminar esta pasta para sempre?
Obrigado a todos pelos conselhos úteis.
Entrando bem no território do StackOverflow, resolvi o problema criando este trecho de código C#. Ele usa a biblioteca Delimon.Win32.IO que aborda especificamente problemas de acesso a caminhos de arquivo longos.
Apenas no caso de isso poder ajudar alguém, aqui está o código - ele ultrapassou os ~ 1600 níveis de recursão com os quais eu estava preso e levou cerca de 20 minutos para removê-los todos.
Pode ser um ponto de junção recursivo. Tal coisa pode ser criada com
junction
um utilitário de arquivo e disco da Sysinternals .E agora você pode ir infinitamente para baixo c:\Hello\Hello\Hello.... (bem até MAX_PATH ser alcançado, 260 caracteres para a maioria dos comandos, mas 32.767 caracteres para algumas funções da API do Windows).
Uma lista de diretórios mostra que é uma junção:
Para excluir, use o utilitário de junção:
Não é uma resposta, mas não tenho representante suficiente para um comentário.
Certa vez, consertei esse problema em um enorme disco FAT16 de 500 MB em um sistema MS-DOS. Usei a depuração do DOS para despejar e analisar manualmente a tabela de diretórios. Em seguida, inverti um bit para marcar o diretório recursivo como excluído. Minha cópia de Dettman e Wyatt 'DOS Programmers' Reference' me mostrou o caminho.
Ainda estou extremamente orgulhoso disso. Eu ficaria surpreso e apavorado se houvesse alguma ferramenta de uso geral que tivesse tanto poder sobre volumes FAT32 ou NTFS. A vida era mais simples naquela época.
Java também pode lidar com caminhos de arquivo longos. E pode fazê-lo muito mais rápido também. Este código (que copiei da documentação da API Java) excluirá uma estrutura de diretório de 1600 níveis em cerca de 1 segundo (no Windows 7, Java 8.0) e sem risco de estouro de pilha, pois na verdade não usa recursão.
Você não precisa de nomes de caminho longos se
chdir
entrar no diretório e apenas usar caminhos relativos pararmdir
.Ou, se você tiver um shell POSIX instalado ou portar para o equivalente em DOS:
(Usar uma variável de shell para rastrear onde você a renomeou para a condição de loop é a outra alternativa para desenrolar o loop como fiz lá.)
Isso evita a sobrecarga da CPU da solução KenD, que força o sistema operacional a percorrer a árvore do topo ao
n
décimo nível toda vez que um novo nível é adicionado, verificando permissões, etc. Portanto, hásum(1, n) = n * (n-1) / 2 = O(n^2)
complexidade de tempo. As soluções que eliminam um pedaço desde o início da cadeia devem serO(n)
, a menos que o Windows precise percorrer uma árvore ao renomear seu diretório pai. ( Linux /chdir
Unix não). diretórios pai a cada chamada do sistema, quando você faz coisas enquanto está em CD em algum lugar.chdir
O(n)
find Folder1 -depth -execdir rmdir {} +
executará rmdir enquanto estiver em CD no diretório mais profundo. Ou, na verdade, a-delete
opção find funciona em diretórios e implica-depth
. Entãofind Folder1 -delete
deve fazer exatamente a mesma coisa, mas mais rápido. Sim, o GNU find no Linux desce verificando um diretório, CDing para subdiretórios com caminhos relativos, depoisrmdir
com um caminho relativo e, em seguida,chdir("..")
. Ele não verifica novamente os diretórios enquanto sobe, portanto, consumiriaO(n)
RAM.Isso foi realmente uma aproximação:
strace
mostra que REALMENTE usaunlinkat(AT_FDCWD, "tmp", AT_REMOVEDIR)
,open("..", O_DIRECTORY|...)
efchdir(the fd from opening the directory)
, com um monte defstat
chamadas misturadas também. Mas o efeito é o mesmo se a árvore de diretórios não for modificada durante a execução do find.editar: Só por diversão, tentei isso no GNU/Linux (Ubuntu 14.10, em uma CPU Core2Duo de primeira geração de 2,4 GHz, em um sistema de arquivos XFS em uma unidade WD 2.5TB Green Power (WD25EZRS)).
(mkdir -p cria um diretório e quaisquer componentes de caminho ausentes).
Sim, realmente 0,05 segundos para 2k rmdir ops. O xfs é muito bom em agrupar operações de metadados no diário, pois eles corrigiram as operações de metadados lentas há 10 anos.
No ext4, criar levou 0m0,279s, excluir com localizar ainda levou 0m0,074s.
Eu também tive isso, em um sistema autônomo do Windows 10. C:\User\Name\Repeat\Repeat\Repeat\Repeat\Repeat\Repeat\Repeat aparentemente até o infinito.
Eu poderia navegar usando o Windows ou o Prompt de Comando até o 50º e não mais. Não consegui excluí-lo, nem clicar nele, etc.
C é minha linguagem, então eventualmente escrevi um programa com um loop de chamadas de sistema, que se repetem até falharem. Você pode fazer isso em qualquer idioma, até mesmo em lote do DOS. Criei um diretório chamado tmp e movi Repeat\Repeat para ele, excluí a pasta Repeat agora vazia e movi tmp\Repeat de volta para a pasta atual. Uma e outra vez!
ChkSystem apenas executa uma chamada system() e verifica o valor de retorno, parando se falhar.
É importante ressaltar que falhou várias vezes. Achei que talvez meu programa não estivesse funcionando ou que, afinal, era infinitamente longo. No entanto, já tive isso antes com chamadas de sistema, com coisas não sincronizadas, então executei o programa novamente e ele continuou de onde parou, então não pense imediatamente que seu programa não está funcionando. Portanto, no total, depois de executá-lo cerca de 20 vezes, limpou todos eles. No total, eram cerca de 1280 pastas originalmente. Não faço ideia do que causou isso. Louco.
Eu me deparei com o mesmo problema com uma bagunça de pastas com mais de 5000 diretórios que algum aplicativo Java fez e escrevi um programa que o ajudará a remover essa pasta. Todo o código fonte está neste link:
https://imanolbarba.net/gitlab/imanol/DiREKT
Ele removeu tudo depois de um tempo, mas conseguiu fazer o trabalho, espero que ajude as pessoas que (como eu) se deparam com o mesmo problema frustrante