Como excluir um grande número de arquivos no Windows


22

Eu tenho um diretório que contém milhões de subdiretórios e trilhões de arquivos. E agora eu tenho que esclarecer isso. Dizendo trilhões, não estou falando sobre o tamanho do arquivo, mas o número de arquivos.

Tentei excluí-lo del/se usar o Windows Explorer. Nem pode concluir a tarefa. Eu tentei excluir alguns dos subdiretórios um por um, e isso me levou dias. O problema que encontrei foi que, toda vez que, independentemente do uso delou do Explorer, posso ver no Gerenciador de Tarefas que a instância do explorer consome memória altíssima e, gradualmente, leva o sistema a travar.

Ainda existem algumas centenas de milhões de arquivos a serem excluídos. Existe alguma possibilidade de alcançar com um (ou apenas alguns) comandos / ações?


[EDITADO]

Eu tentei fazê-lo com Cygwin rm -fre obtive o mesmo resultado. Resumido como:

  1. Não importa o uso do Windows Explorer, DELno prompt de comando ou no rmcomando Cygwin , a memória do sistema cai gradualmente para zero e a caixa irá travar.

  2. Se a qualquer momento, antes do sistema falhar, o processo estiver fechado (por CTRL + C ou o que mais), a caixa continuará funcionando normalmente. No entanto, toda a memória usada NÃO será liberada. Digamos, parei o processo enquanto a memória do sistema atinge 91%, o Gerenciador de Tarefas informa: 4G RAM total, cache é 329M e 335MB disponível. Então, o uso da memória permanecerá nesse nível até eu reiniciar a máquina. Se eu interromper a instância do explorer no Gerenciador de tarefas, a tela ficará em branco com a luz do disco rígido o tempo todo ligada e nunca mais voltará. Normalmente, quando eu paro a instância do explorer no Gerenciador de Tarefas, posso invocá-la novamente pressionando Win + E, ou ela foi reiniciada automaticamente.

Bem, gerenciamento de memória muito bom!


[EDITAR NOVAMENTE] Parece que parte da memória usada foi liberada após um longo tempo, mas não toda. Parte da memória em cache e disponível voltou ao Gerenciador de tarefas. Não esperei mais, não tenho certeza do que acontecerá então.


Portanto, seu principal problema é o fato de que diretórios e subdiretórios não estão sendo excluídos?
Sandeep Bansal

@ Jackey Cheung: qual versão do Windows você está usando?
Siva Charan

11
Você pode escrever um script em lote que exclua recursivamente os arquivos, não começando do nível superior, mas, por exemplo, no quinto nível da estrutura de pastas. Que iria dividir o trabalho em muitos separada e sequencial 'rm de

9
Eu tenho que saber, como diabos você conseguiu um trilhão de arquivos, realmente ...
Moab

2
Um trilhão de arquivos precisa de uma tabela de arquivos de 1 PB. Os maiores discos rígidos da atualidade são alguns TB. Como você conseguiu uma partição tão grande?
quer

Respostas:


10

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 /ropção em vez de recursão (manual). Isso não funcionaria porque, embora o /rswitch 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 = 400diretó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.


Tenho certeza que isso não funciona. Eu tentei. O problema está no loop FOR. Descobriu-se que o FOR causará o mesmo problema que emitir DEL diretamente.
Jackey Cheung

11
Depende dos switches que você usa. Se você usou o /rswitch, como expliquei, ele tentará enumerar todos os arquivos. Se você usar a /dopção, ela enumera apenas as pastas no diretório atual; portanto, a menos que você tenha um bilhão de pastas no diretório atual, isso não deve causar problemas.
21413 Synetech

7

Não consigo falar com trilhões de arquivos, mas recentemente reduzi um compartilhamento de arquivo antigo que continha ~ 1,8 milhão de arquivos usando:

robocopy EmptyTMPFolder FolderToDelete /MIR /MT:16 /ETA /R:30 /W:5

"EmptyTMPFolder" é um diretório local vazio. a opção / MIR fará com que o destino pareça com a fonte (vazia).

O benefício real dessa abordagem foi a opção de repetição (/ R: 30). Isso permitiu uma oportunidade de absorver quaisquer problemas de conectividade que possam ocorrer durante esse processo. Exclusões locais podem não encontrar benefícios nessa abordagem.

Não tenho benchmarks específicos para comparar os tempos, mas preferiria isso a algumas das outras opções sugeridas b / c das opções de repetição / espera. As exclusões começaram quase instantaneamente.


Descobri que esse é de longe o método mais eficiente ao executar a limpeza em uma grande árvore de pastas de unidades de rede. Obrigado pela dica.
Tonny

5

A exclusão de todas as pastas levará muito tempo e não há muito o que fazer. O que você pode fazer é salvar seus dados e formatar sua unidade. Não é o ideal, mas funcionará (e rapidamente).

Outra opção é talvez usar alguma distribuição Linux em um CD ao vivo que possa ler de uma partição NTFS. Sei por experiência pessoal que rm -rf folderNamepode ser executado por pelo menos 2 dias sem travar um sistema com 2 GB de RAM. Vai demorar um pouco, mas pelo menos vai terminar.


11
hm, Linux. Estou pensando no Cygwin. Embora seja suposto usar funções sublinhadas do Windows, apenas me pergunto se isso fará alguma diferença no caso. Vou experimentar.
precisa saber é o seguinte

11
você pode usar git festa
gota de chuva

4

Não quero saber como você criou tantos.

O que está acontecendo é que o Explorer está tentando enumerar todos os arquivos e armazenar as informações na memória antes de começar a excluir. E obviamente há muitos.

Você já tentou o comando rmdir /s? Contanto que ele realmente exclua os arquivos à medida que são encontrados, em vez de esperar que cada um seja enumerado, pode funcionar.

Quantos níveis de subdiretórios existem? Se houver apenas um ou outro número baixo, um arquivo em lote rápido que retorne manualmente poderá funcionar.

Qualquer método vai demorar um pouco, no entanto.


Além da sugestão de reformatação dos soandos, é claro. Isso seria rápido, mas se esta for a unidade do sistema, você precisará reinstalar o Windows.
24412 Bob

Tenho certeza de que a enumeração deve ocorrer, apenas para que o programa saiba o que excluir em seguida. O rmdir não pode excluir os arquivos conforme eles são encontrados, pois começa do topo e precisa percorrer de alguma forma. A única questão é quanto excesso de informação ele armazena.
soandos

O @soandos Explorer conta todos os arquivos. Eu estava pensando em algum método que implementa um estilo de enumeração DFS: indo o mais longe possível para um ramo, excluindo quando ele atinge um arquivo, antes de voltar. Em outras palavras, recursão, que é o que rm -rffaz. Isso funciona melhor com estruturas de diretório relativamente rasas. Não tenho certeza se rmdir /sfaz isso. Ele deveria .
Bob

11
@JackeyCheung rmdir /?: /s Removes all directories and files in the specified directory in addition to the directory itself. Used to remove a directory tree.Em outras palavras, a /sbandeira também remove arquivos. Como você usou del? E sim, pode ser melhor usar apenas rm -rfcomo sugerido.
24412 Bob

11
@JackeyCheung: você está errado. Se você der o sinalizador / s para rmdir, ele excluirá os arquivos e os diretórios.
Harry Johnston

4

Uma causa possível de um problema como esse é o provisionamento thin, normalmente encontrado em ambientes SAN. Algumas unidades de estado sólido podem exibir o mesmo problema. Se for esse o caso, essa alteração na configuração pode resolver seu problema:

fsutil behavior set DisableDeleteNotify 1

Observe que essa alteração pode afetar o desempenho das unidades de estado sólido e impedir o retinamento automático e / ou manual das unidades SAN.



3

Provavelmente é o seu antivírus / antimalware consumindo toda a memória e depois travando o sistema.

O próprio Windows não tem problemas para excluir um grande número de arquivos, embora certamente seja mais lento que uma operação semelhante na maioria dos sistemas de arquivos que não são da Microsoft.


Bom ponto! Certamente vale a pena dar uma olhada.
Jackey Cheung

Desliguei o antivírus e a memória ainda foi consumida como antes.
Jackey Cheung

Desativar o antivírus também não ajuda a liberar memória depois que o processo é interrompido.
Jackey Cheung

@JackeyCheung: Que programa antivírus é esse? Alguns realmente não desligar completamente ...
Ben Voigt

2

Um problema que você pode estar enfrentando é que o diretório não é compactado quando você exclui um arquivo / pasta; portanto, se você tiver uma pasta com 1 milhão de arquivos e exclua os primeiros 500k deles. Há vários blocos no início do diretório que estão em branco para todos os efeitos.

MAS, o explorer e um prompt de comando ainda precisam examinar esses blocos para o caso de haver um arquivo lá. Algo que pode ajudar é "mover" uma pasta de algum lugar abaixo da árvore para uma nova pasta fora da base da unidade e excluir essa nova pasta. Mover a pasta moverá apenas o ponteiro para a pasta, de forma que ela vá rapidamente e não mova todos os arquivos nela para um novo espaço na unidade.

Outra coisa que você pode tentar é usar uma ferramenta de terceiros como "PerfectDisk" para compactar pastas depois de excluir um monte de arquivos.


2

Tentando várias abordagens para excluir mais de 10 milhões de arquivos de log de fusão, notei que cerca de 30 mil arquivos poderiam ser excluídos em um período de 10 minutos. Isso levaria cerca de 55 horas para os 10 milhões de arquivos ...

Usando o script abaixo, a taxa de exclusão aumentou em ~ 75%. As listas de arquivos são criadas e executadas por processos simultâneos, aumentando as operações do disco (mas não linearmente). Estou mostrando 4 garfos, mas dois podem ser suficientes.

Há uma opção para usar o PowerShell, que reduz significativamente o tempo necessário para preparar as listas.

BTW, eu testei usando duas operações de deleção direta, permitindo colisões, mas não houve redução perceptível no tempo de exclusão geral em comparação com uma única operação de deleção. Embora não seja desejável criar listas de exclusão, o tempo economizado valeu a pena.

@ECHO OFF
SETLOCAL EnableDelayedExpansion

IF /I "%~1"=="timestamp" (
    CALL :ECHOTIMESTAMP
    GOTO END
)

rem directory structure to delete
SET "DELETE=c:\_delete\Content.IE5\???<<<change this>>>???"
rem primary list of discovered files to delete
SET "LIST=delete-list.txt"
rem base path for sub-lists
SET "LISTBASE=.\delete-list"
SET "TITLE=Batch Delete Process"
rem specifies number of batch delete processes to spawn
SET FORKS=4
rem when set to 1, use PowerShell for list building and delete.  Definitely improves time to build fork sublists
SET POWERSHELL=0
rem specifies max files to delete when greater than 0
SET MAXDEL=1000000

rem prompt for confirmatoin
SET /P CONT=About to delete all files and directories from !DELETE!. Continue (Y/N)?
IF /I NOT "!CONT!"=="Y" EXIT /B

CALL :ECHOTIMESTAMP

ECHO Accumulating list of files to delete...
dir /b /s "!DELETE!" > "!LIST!"

FOR /F "delims=" %%c IN ('type "!LIST!" ^| find /C ":"') DO SET "COUNT=%%c"
ECHO Discoverd !COUNT! files and directories to delete.

IF  %MAXDEL% GTR 0 IF !COUNT! GTR %MAXDEL% (
    SET COUNT=%MAXDEL%
    ECHO Limiting files/directories deletion count to  !COUNT!
)

CALL :ECHOTIMESTAMP
ECHO Preparing !FORKS! delete processes...
SET /A LIMIT=!COUNT!/!FORKS!

IF !POWERSHELL! EQU 1 (
    SET SKIP=0
    FOR /L %%n IN (1,1,!FORKS!) DO (
        SET "CURRENT=!LISTBASE!-%%n.txt"
        SET "LIST[%%n]=!CURRENT!"
        DEL /f /q "!CURRENT!" > nul 2>&1
        IF %%n EQU !FORKS! SET /A LIMIT+=!FORKS!
        SET CMD=type \"!LIST!\" ^| select -first !LIMIT! -skip !SKIP!
        powershell -command "& {!CMD!}" > "!CURRENT!"
        SET /A SKIP+=!LIMIT!
    )

) ELSE (
    rem significantly slower but no PowerShell.
    SET L=1
    SET N=!LIMIT!
    SET C=0
    FOR /F %%f  IN (!LIST!) DO (
        IF !C! LSS !COUNT! (
            IF !N! GEQ !LIMIT! (
                SET "CURRENT=!LISTBASE!-!L!.txt"
                SET "LIST[!L!]=!CURRENT!"
                DEL /f /q "!CURRENT!" > nul 2>&1
                SET /A L+=1
                SET /A N=0
            ) ELSE (
                SET /A N+=1
            )
            ECHO %%f >> "!CURRENT!"
        ) ELSE (
            GOTO ENDLIST
        )
        SET /A C+=1
    )
)
:ENDLIST

CALL :ECHOTIMESTAMP
ECHO Forking !FORKS! delete processes...
FOR /L %%t IN (1,1,!FORKS!) DO (

    SET "CURRENT=!LIST[%%t]!"
    IF !POWERSHELL! EQU 1 (
        SET "TAB=        "
        SET BLANK=!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!
        SET BLANK=!BLANK!!BLANK!!BLANK!!BLANK!
        SET DEL_CMD=del -force -recurse -ea SilentlyContinue -path \"$_\"
        SET $W_CMD=$w=$Host.UI.RawUI.WindowSize.Width
        SET $S_CMD=$s=\"$_\";$i=[math]::max^(0,$s.length-$w^);$s=$s.substring^($i, $s.length-$i^);$s=\"$s !BLANK!\";$s=$s.substring^(0,[math]::min($w,$s.length^)^)
        SET ECHO_CMD=Write-Host \"`r$s\" -NoNewLine
        SET CMD=type \"!CURRENT!\" ^| %% {!DEL_CMD!; !$W_CMD!; !$S_CMD!; !ECHO_CMD!}
        SET CMD=powershell -command "^& {!CMD!}" ^& ECHO\ ^& "%~dpnx0" timestamp
        ECHO CMD !CMD!
    ) ELSE (
        SET LOOP=FOR /F %%%f IN ^(!CURRENT!^) DO
        SET OP=del "%%%f"
        SET CMD=@ECHO OFF ^&^& ^(!LOOP! !OP!  ^> nul 2^>^&1 ^)  ^& "%~dpnx0" timestamp
    )
    rem ECHO !CMD!
    START "!TITLE! %%t" cmd /k  !CMD!
)

GOTO END

:ECHOTIMESTAMP
SETLOCAL
    SET DATESTAMP=!DATE:~10,4!-!DATE:~4,2!-!DATE:~7,2!
    SET TIMESTAMP=!TIME:~0,2!-!TIME:~3,2!-!TIME:~6,2!
    ECHO !DATESTAMP: =0!-!TIMESTAMP: =0!
ENDLOCAL
GOTO :EOF

:END
ENDLOCAL
EXIT /B

2

Experimente e modifique conforme necessário.

É um script testado no Win2003, com base na explicação e análise técnica da Synetech, respondida em 15/10 '13 às 15:22

@echo off

rem ### USE FULL PATH AS FIRST ARGUMENT TO SCRIPT, DONT FORGET QUOTES !
rem ### If you move this script, fix script path variable...
SET STATICFULLSCRIPTPATH="D:\scripts\FOLDER"
SET SCRIPTNAME="DeleteFast.bat"

rem ### If CD fails or IF condition has problems,
rem ### and DEL or RMDIR runs, its better to be at safe place.
if not exist "%TEMP%\SAFE" mkdir "%TEMP%\SAFE"
if exist "%TEMP%\SAFE" cd /d "%TEMP%\SAFE"

rem ### Fix quote overflow
set var1="%1"
set var1=%var1:"=%

if not [%1]==[] (
    cd /d "%var1%"

    echo # KILLING F AT : "%var1%"
    rem ### uncomment to do damage! ### 
    rem # del /f/q * > nul

    for /d %%i in (*) do call "%STATICFULLSCRIPTPATH%\%SCRIPTNAME%" "%var1%\%%i"

    rem ## Finish deleting the last dir
    cd /d "%var1%\.."

echo # KILLING  DIR : "%var1%"
rem ## Remove dir.. first try
rmdir /q "%var1%"

if exist "%var1%" (
    rem ## Remove dir.. second try
    rem ## If thousands of files/dirs had permission/ownership problems, then prepare to wait a long time.
    rem ### uncomment to do damage! ### 
    rem #cmd.exe /c takeown /f "%var1%" && icacls "%var1%" /grant SOMEBODY:F

    rem ### uncomment to do damage! ### 
    rem #rmdir /s/q "%var1%"
)
)

cd /d "%STATICFULLSCRIPTPATH%"

Testrun .. Existem pastas como A1 a A4, B1 a B4 e C1 a C4 aninhadas de maneira diferente.

Z:\>"D:\scripts\FOLDER\DeleteFast.bat" "D:\scripts\TESTF\DIRS"
# KILLING F AT : "D:\scripts\TESTF\DIRS"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B1\C 1"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B1\C 1"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B2"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B2\C 2"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B2\C 2"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B2"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A2"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A2\B3"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A2\B3\C 3"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A2\B3\C 3"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A2\B3"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A2"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A3"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A3\B4"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A3\B4\C 4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A3\B4\C 4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A3\B4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A3"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS"

D:\scripts\FOLDER>

Não posso comentar (o site reclama da minha reputação), então adiciono meu comentário aqui ..

A solução do Bjv cria listas de arquivos temporárias inúteis. E depois reitera-os pela segunda vez para fazer o trabalho real. /superuser//a/892412/528695

O script original da Synetech não funcionou para mim. /superuser//a/416469/528695

@echo off
if not [%1]==[] cd /d %1
echo "%1"
for /d %%i in (*) do call %0 "%%i"

Resultados..

Z:\>C:\privscripts\TESTF\DeleteFastORIGINAL.bat "C:\privscripts\TESTF\DIRS"
""C:\privscripts\TESTF\DIRS""
""A1""
""B1""
""C1""
The system cannot find the path specified.
""B2""
The system cannot find the path specified.
""A2""
The system cannot find the path specified.
""A3""
The system cannot find the path specified.
""A4""

C:\privscripts\TESTF\DIRS\A1\B1\C1>

Posso verificar se @ user4350129 está correto quando ele diz que o script da Synetech não funciona - eu tive o mesmo comportamento na minha caixa Win7x64.
precisa saber é o seguinte

Porra, meu script também não era perfeito, problemas com se o argumento em falta e o estouro de citações quebravam os comandos assumidos e os icacls .. também só verifiquei pastas e não arquivos. Corrigi esses problemas. Pós-editados, mas sempre teste antes de usar.
EO

2

Eu tive problemas semelhantes há muito tempo com apenas 10 milhões de arquivos, mas em um servidor 2003, para excluir os arquivos, usei um servidor / cliente ftp e deixei o cliente excluindo os arquivos e pastas. É uma solução lenta, mas funciona perfeita.

Provavelmente, você terá um segundo problema com a MFT no NTFS que não tem solução, a MFT é uma matriz que no Windows 2003 (não tenho certeza se a Microsoft tem uma solução após o Windows 2003) está armazenando todos os arquivos de maneira incremental. com trilhões de arquivos, o tamanho será louco, no meu caso, a MFT tinha 17 milhões de registros e o tamanho da MFT era de 19 GB com apenas 45.000 arquivos, testei em outros sistemas e parece que, com 1 milhão de registros, a MFT ter cerca de 1 GB.

Você pode verificar o status da MFT com este comando:

defrag C: /a /v
  • C: - letra da unidade
  • /a - analisar
  • /v - detalhado

Outra solução complicada, já que não há ferramenta que possa reduzir a MFT, as ferramentas apenas preenchem com 0 o nome dos arquivos e propriedades, mas nada mais, mas você pode usar o VMware converter ou outro tipo de P2V e criar uma máquina virtual baseada em seu servidor, dessa forma você resolverá todos os problemas relacionados à MFT, nunca testei a conversão do V2P, agora estou trabalhando apenas em ambientes virtuais, mas vi muitas informações sobre ele na internet.

Essa vitória de 2003 está funcionando perfeitamente agora, o tamanho da MFT é de 40MB e está tudo bem, se você quiser, posso falar mais sobre backups, desfragmentações ou outras tarefas relacionadas a milhões de arquivos minúsculos.



1

Como a exclusão dos arquivos de uma só vez utiliza muita memória, você precisa de uma maneira de excluí-los um de cada vez, mas com o processo automatizado. Esse tipo de coisa é muito mais fácil de fazer em um shell no estilo Unix, então vamos usar o Cygwin. O comando a seguir gera uma lista de arquivos comuns, transforma essa lista em uma sequência de rmcomandos e alimenta o script resultante em um shell.

 find dir \! -type d | sed 's/^/rm /' | sh

O script está sendo executado mesmo quando está sendo gerado, e não há loops; portanto, esperamos que o shell não precise criar grandes arquivos temporários. Certamente vai demorar um pouco, já que o script tem milhões de linhas. Você pode precisar ajustar o rmcomando (talvez eu devesse ter usado -f? Mas você entende seus arquivos melhor que eu) para fazê-lo funcionar.

Agora você não tem mais nada além de diretórios. Aqui é onde as coisas ficam difíceis. Talvez você tenha excluído arquivos suficientes para ficar rm -rfsem memória (e provavelmente será mais rápido que outro script). Caso contrário, podemos adaptar esta resposta do Stackoverflow :

 find dir | perl -lne 'print tr:/::, " $_"' | sort -n | cut -d' ' -f2 | sed 's/^/rmdir /' | sh

Novamente, pode ser necessário ajustar, desta vez com sort, para evitar a criação de grandes arquivos temporários.


1

Encontrei o mesmo problema há algum tempo. Eu escrevi um pequeno utilitário que faz exatamente isso: exclua recursivamente um diretório. Ele não enumerará os arquivos e não consumirá muita memória (O (n + m) no máximo com n = profundidade máxima do diretório e m = contagem máxima de arquivos / diretórios em um dos subdiretórios). Ele pode lidar com caminhos de arquivo longos (> 256 caracteres). Gostaria de receber feedback se você puder resolver seu problema com isso.

Você pode encontrá-lo aqui: https://github.com/McNetic/fdeltree (executável na pasta releases)


1

Eu encontrei esse segmento procurando uma maneira melhor do que eu tinha para excluir mais de 3 milhões de arquivos em vários servidores que eu suporte. As opções acima são muito complicadas, então acabei usando meu método conhecido de usar a ferramenta de linha de comando "FORFILES" no Windows (isso foi no Server 2003).

De qualquer forma, abaixo está o comando FORFILES que usei para excluir TODOS os arquivos em uma pasta da linha de comando.

forfiles / P "SEU CAMINHO DE PASTA AQUI (por exemplo, C: \ Windows \ Temp)" / C "cmd / c eco @file & del / f / q @file"

O ECHO acima também é o nome dos arquivos que estão sendo excluídos na tela, mas apenas porque eu queria ver algum progresso dele realmente fazendo algo, se você não repetir algo, parece que a caixa do DOS está travada, embora esteja fazendo o trabalho como esperado.

Demora um pouco para iniciar, ou seja, parece que não está fazendo nada por um tempo (cerca de 30m para ~ 3 milhões de arquivos), mas eventualmente você deve ver os nomes dos arquivos começarem a aparecer à medida que são excluídos. Esse método também leva muito tempo para excluir os arquivos (o tempo de exclusão pode ser reduzido sem o eco?), Mas eventualmente funciona sem travar a máquina, nos arquivos do meu servidor, os arquivos do servidor estavam usando ~ 1.850Kb de memória durante o processo de exclusão. .

A duração da exclusão pode causar um problema se seus servidores tiverem logoff automático, pois você precisará manter o mouse em movimento (eu recomendo executar como usuário do console ou através de uma ferramenta de terceiros, como LanDesk ou SCCM etc.) ou MouseJiggle. Exe))

Enfim, pensei em compartilhar minha resposta, boa sorte a todos!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.