Jak usunąć ogromną liczbę plików w systemie Windows


22

Mam katalog zawierający miliony podkatalogów i tryliony plików. A teraz muszę to wyczyścić. Mówiąc bilion, nie mówię o rozmiarze pliku, ale o liczbie plików.

Próbowałem go usunąć za del/spomocą Eksploratora Windows. Żadne nie może wykonać zadania. Próbowałem usuwać niektóre podkatalogi jeden po drugim i zajęło mi to kilka dni. Problem, który napotkałem, polegał na tym, że za każdym razem, bez względu na użycie dellub Eksploratora, widzę w Menedżerze zadań, że instancja eksploratora zużywa niebotyczną pamięć i stopniowo popycha mój system do awarii.

Nadal jest kilkaset milionów plików do usunięcia. Czy jest jakaś szansa na osiągnięcie jednego (lub kilku) poleceń / działań?


[EDYTOWANE]

Próbowałem zrobić to z Cygwin rm -fri przyniosłem ten sam wynik. Podsumowane jako:

  1. Bez względu na użycie Eksploratora Windows, DELz wiersza polecenia lub rmpolecenia Cygwin , pamięć systemowa stopniowo spada do zera, a pudełko ostatecznie się zawiesi.

  2. Jeśli w dowolnym momencie, przed awarią systemu, proces zostanie zamknięty (za pomocą CTRL + C lub cokolwiek innego), pudełko będzie nadal działać normalnie. Jednak cała wykorzystana pamięć NIE zostanie zwolniona. Powiedzmy, że zatrzymałem proces, podczas gdy pamięć systemowa osiąga 91%, Menedżer zadań mówi: Łącznie 4G RAM, pamięć podręczna to 329 MB i dostępne 335 MB. Następnie użycie pamięci pozostanie na tym poziomie, dopóki nie uruchomię ponownie komputera. Jeśli zatrzymam instancję eksploratora w Menedżerze zadań, ekran zgaśnie po włączeniu światła dysku twardego i nigdy nie wróci. Zwykle po zatrzymaniu instancji eksploratora w Menedżerze zadań mogę ponownie ją wywołać, naciskając Win + E lub automatycznie zrestartowano ją.

Naprawdę fajne zarządzanie pamięcią!


[EDYCJA PONOWNIE] Wygląda na to, że część użytej pamięci została zwolniona po dłuższej chwili, ale nie wszystkie. Część pamięci podręcznej i dostępnej wróciła w Menedżerze zadań. Nie czekałem już dłużej, nie jestem pewien, co się wtedy stanie.


Więc twoim głównym problemem jest to, że katalogi i podkatalogi nie są usuwane?
Sandeep Bansal

@Jackey Cheung: z której wersji systemu Windows korzystasz?
Siva Charan

1
Możesz napisać skrypt wsadowy, który rekurencyjnie usuwa pliki, nie zaczynając od najwyższego poziomu, ale np. Na piątym poziomie struktury folderów. To podzieliłoby zadanie na wiele oddzielnych i sekwencyjnych 'rm'

9
Muszę wiedzieć, jak, u diabła, dostałeś bilion plików, naprawdę ...
Moab,

2
Bilion plików potrzebuje tabeli plików o wielkości 1 PB. Największe dyski twarde mają obecnie kilka TB. Jak mogłeś uzyskać tak dużą partycję?
user541686,

Odpowiedzi:


10

Wyjaśnienie techniczne

Przyczyną problemów jest większość metod, ponieważ system Windows próbuje wyliczyć pliki i foldery. Nie stanowi to większego problemu w przypadku kilkuset - a nawet tysięcy - plików / folderów o głębokości kilku poziomów, ale jeśli masz biliony plików w milionach folderów sięgających dziesiątek poziomów, to z pewnością zapełni system. .

Załóżmy, że masz „tylko” 100 000 000 plików, a system Windows używa takiej prostej struktury do przechowywania każdego pliku wraz z jego ścieżką (w ten sposób unikniesz przechowywania każdego katalogu osobno, oszczędzając w ten sposób pewien narzut):

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
}

W zależności od tego, czy używa znaków 8-bitowych, czy znaków Unicode (używa Unicode) i czy twój system jest 32-bitowy czy 64-bitowy, wtedy będzie potrzebował od 25 GB do 49 GB pamięci do przechowywania listy (i jest to bardzo uproszczona struktura).

Powód, dla którego system Windows próbuje wyliczyć pliki i foldery przed ich usunięciem, różni się w zależności od metody, której używasz do ich usunięcia, ale robią to zarówno Eksplorator, jak i interpreter poleceń (możesz zauważyć opóźnienie po zainicjowaniu polecenia). Możesz także zobaczyć miganie aktywności dysku (dioda LED dysku twardego) podczas odczytywania drzewa katalogów z napędu.

Rozwiązanie

Najlepszym rozwiązaniem tego problemu jest skorzystanie z narzędzia do usuwania, które usuwa pliki i foldery pojedynczo, pojedynczo. Nie wiem, czy są na to gotowe narzędzia, ale to powinno być możliwe za pomocą prostego pliku wsadowego.

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

Spowoduje to sprawdzenie, czy argument został przekazany. Jeśli tak, to zmienia się na podany katalog (można go uruchomić bez argumentu, aby uruchomić w bieżącym katalogu lub podać katalog - nawet na innym dysku, aby miał się tam uruchomić).

Następnie usuwa wszystkie pliki w bieżącym katalogu. W tym trybie nie powinien niczego wyliczać i po prostu usuwać pliki bez zużywania dużej, jeśli w ogóle, pamięci.

Następnie wylicza foldery w bieżącym katalogu i wywołuje się, przekazując każdy folder do siebie (siebie), aby powrócić w dół.

Analiza

Powodem tego powinno być to, że nie wylicza każdego pojedynczego pliku i folderu w całym drzewie . W ogóle nie wylicza żadnych plików i tylko wylicza foldery w bieżącym katalogu (plus pozostałe w katalogach nadrzędnych). Zakładając, że w danym folderze znajduje się tylko kilkaset podkatalogów, nie powinno to być takie złe i na pewno wymaga znacznie mniej pamięci niż inne metody, które wyliczają całe drzewo.

Możesz zastanawiać się nad użyciem /rprzełącznika zamiast (ręcznej) rekurencji. To nie zadziałałoby, ponieważ podczas gdy /rprzełącznik wykonuje rekurencję, wstępnie wylicza całe drzewo katalogów, czego dokładnie chcemy uniknąć; chcemy je usuwać bez przechodzenia.

Porównanie

Porównajmy tę metodę z metodą (metodami) pełnego wyliczania.

Powiedziałeś, że masz „miliony katalogów”; powiedzmy 100 milionów. Jeśli drzewo jest w przybliżeniu zrównoważone i zakłada średnio około 100 podkatalogów na folder, to najgłębiej zagnieżdżony katalog byłby o około cztery poziomy niżej - w rzeczywistości w całym drzewie byłoby 101 010 100 podfolderów. (Zabawne, jak 100M może rozbić się do 100 i 4).

Ponieważ nie wyliczamy plików, musimy śledzić maksymalnie 100 nazw katalogów na poziom, dla maksymalnie 4 × 100 = 400katalogów w danym momencie.

Dlatego zapotrzebowanie na pamięć powinno wynosić ~ 206,25 KB, a więc w granicach dowolnego nowoczesnego (lub innego) systemu.

Test

Niestety (?) Nie mam systemu z bilionami plików w milionach folderów, więc nie jestem w stanie go przetestować (wydaje mi się, że na koniec liczyłem około 800 tysięcy plików), więc ktoś inny będzie musiał spróbować to.

Zastrzeżenie

Oczywiście pamięć nie jest jedynym ograniczeniem. Dysk będzie również dużym wąskim gardłem, ponieważ dla każdego usuwanego pliku i folderu system musi oznaczyć go jako wolny. Na szczęście wiele z tych operacji na dyskach zostanie połączonych razem (w pamięci podręcznej) i zapisanych we fragmentach zamiast osobno (przynajmniej dla dysków twardych, a nie dla nośników wymiennych), ale nadal będzie powodowało sporo wstrząsów podczas odczytywania systemu i zapisuje dane.


Jestem prawie pewien, że to nie działa. Próbowałem Problem leży w pętli FOR. Okazało się, że FOR spowoduje ten sam problem, co bezpośrednie wydawanie DEL.
Jackey Cheung

1
To zależy od używanych przełączników. Jeśli użyłeś /rprzełącznika, to jak wyjaśniłem, spróbuje wyliczyć wszystkie pliki. Jeśli użyjesz /dprzełącznika, wyliczy on tylko foldery w bieżącym katalogu, więc jeśli nie masz miliarda folderów w bieżącym katalogu, nie powinno to powodować problemu.
Synetech

7

Nie mogę rozmawiać z bilionami plików, ale ostatnio nukowałem stary udział plików, który zawierał ~ 1,8 mln plików, używając:

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

„EmptyTMPFolder” to pusty katalog lokalny. opcja / MIR sprawi, że cel będzie wyglądał jak źródło (puste).

Prawdziwą korzyścią z tego podejścia była opcja ponownej próby (/ R: 30). To pozwoliło na pochłonięcie wszelkich problemów z łącznością, które mogą wystąpić podczas tego procesu. Lokalne usuwanie może nie przynieść korzyści w tym podejściu.

Nie mam konkretnych testów porównawczych, ale wolę to niż niektóre inne sugerowane opcje b / c opcji ponów / czekaj. Usunięcia rozpoczęły się niemal natychmiast.


Odkryłem, że jest to zdecydowanie najbardziej wydajna metoda podczas czyszczenia w drzewie folderów na dużym dysku sieciowym. Dziękuję za wskazówkę.
Tonny

5

Usunięcie wszystkich folderów zajmie dużo czasu i niewiele można na to poradzić. Możesz zapisać dane i sformatować dysk. Nie jest optymalny, ale zadziała (i szybko).

Inną opcją jest być może użycie dystrybucji Linuksa na płycie CD na żywo, którą można odczytać z partycji NTFS. Wiem z własnego doświadczenia, że rm -rf folderNamemoże działać przez co najmniej 2 dni bez awarii systemu z 2 GB pamięci RAM. To potrwa chwilę, ale przynajmniej się skończy.


1
hm, Linux. Myślę o Cygwinie. Chociaż należy używać podkreślających funkcji systemu Windows, zastanawiam się, czy w tym przypadku coś zmieni. Spróbuję tego.
Jackey Cheung

1
możesz użyć git bash
kropla deszczu

4

Eee ... Nie chcę wiedzieć, jak stworzyłeś ich tak wiele.

To, co się dzieje, to Explorer próbuje wyliczyć każdy pojedynczy plik i zapisać informacje w pamięci, zanim rozpocznie się usuwanie. I oczywiście jest ich zdecydowanie za dużo.

Czy wypróbowałeś polecenie? rmdir /s ? Tak długo, jak faktycznie usuwa pliki, które zostały znalezione, zamiast czekać na każdy z nich do wyliczenia, może działać.

Ile jest poziomów podkatalogów? Jeśli jest tylko jeden lub inny niski numer, może działać szybki plik wsadowy, który ręcznie się powtarza.

Jednak każda metoda może chwilę potrwać.


Oczywiście poza sugestią Soandos dotyczącą przeformatowania. To byłoby szybkie, ale jeśli jest to dysk systemowy, będziesz musiał ponownie zainstalować system Windows.
Bob

Jestem pewien, że wyliczenie musi mieć miejsce, aby program wiedział, co następnie usunąć. rmdir nie może usuwać plików w momencie ich znalezienia, ponieważ zaczyna się od góry i musi jakoś przechodzić. Jedyne pytanie dotyczy tego, ile przechowywanych informacji o nadmiarze.
soandos

@soandos Explorer liczy każdy plik. Myślałem o pewnej metodzie, która implementuje styl wyliczania DFS: idąc jak najdalej w dół gałęzi, usuwając, gdy trafi do pliku, zanim wróci. Innymi słowy, rekurencja jest tym, co rm -rfdziała. Działa to najlepiej w przypadku stosunkowo płytkich struktur katalogów. Nie jestem pewien, czy rmdir /sto robi. To powinno .
Bob

1
@JackeyCheung rmdir /?: /s Removes all directories and files in the specified directory in addition to the directory itself. Used to remove a directory tree.Innymi słowy, /sflaga usuwa również pliki. Jak korzystałeś del? I tak, może być lepiej używać rm -rfzgodnie z sugestią soandos.
Bob

1
@JackeyCheung: się mylisz. Jeśli podasz rmdir flagę / s, spowoduje to usunięcie plików oraz katalogów.
Harry Johnston,

4

Jedną z możliwych przyczyn takiego problemu jest cienkie przydzielanie, zwykle spotykane w środowiskach SAN. Niektóre dyski półprzewodnikowe mogą wykazywać ten sam problem. W takim przypadku ta zmiana konfiguracji może rozwiązać problem:

fsutil behavior set DisableDeleteNotify 1

Należy pamiętać, że ta zmiana może mieć wpływ na wydajność dysków półprzewodnikowych i może uniemożliwić automatyczne i / lub ręczne ponowne czyszczenie dysków SAN.



3

Prawdopodobnie Twój program antywirusowy / antymalware zużywa całą pamięć, a następnie powoduje awarię systemu.

Sam system Windows nie ma problemu z usunięciem dużej liczby plików, choć z pewnością jest wolniejszy niż podobna operacja w większości systemów plików innych niż Microsoft.


Fajna uwaga! Na pewno warto rzucić okiem.
Jackey Cheung,

Wyłączyłem program antywirusowy, a pamięć wciąż została zjedzona jak poprzednio.
Jackey Cheung,

Wyłączenie programu antywirusowego nie pomaga w zwolnieniu pamięci po zatrzymaniu procesu.
Jackey Cheung,

@JackeyCheung: Który to program antywirusowy? Niektóre nie wyłączają się całkowicie ...
Ben Voigt,

2

Problemem, na który możesz natknąć się, jest to, że katalog nie ulega kompaktowaniu po usunięciu pliku / folderu, więc jeśli masz folder z 1 milionem plików i usuniesz pierwsze 500k z nich. Na początku katalogu jest mnóstwo bloków, które są puste.

ALE, explorer i wiersz poleceń wciąż muszą przeglądać te bloki na wypadek, gdyby tam był plik. Coś, co może pomóc, to „przenieść” folder z jakiegoś miejsca w dół drzewa do nowego folderu z podstawy napędu, a następnie usunąć ten nowy folder. Przeniesienie folderu spowoduje jedynie przeniesienie wskaźnika do folderu, więc powinien on przejść szybko, a nie przenieść wszystkie znajdujące się pod nim pliki na nowe miejsce na dysku.

Inną rzeczą, którą możesz spróbować, jest użycie narzędzia innej firmy, takiego jak „PerfectDisk”, do kompaktowania folderów po usunięciu kilku plików.


2

Próbując różnych metod usuwania ponad 10 milionów plików dziennika syntezy, zauważyłem, że średnio około 30 000 plików można usunąć w ciągu 10 minut. Zajmie to około 55 godzin dla 10 milionów plików ...

Korzystając ze skryptu poniżej, szybkość usuwania wzrosła o ~ 75%. Listy plików są tworzone i wykonywane przez współbieżne procesy zwiększające operacje dyskowe (ale nie liniowo.) Pokazuję 4 widelce, ale dwa mogą wystarczyć.

Istnieje opcja użycia programu PowerShell, co znacznie skraca czas potrzebny na przygotowanie list.

BTW, testowałem przy użyciu dwóch bezpośrednich operacji usuwania pozwalających na kolizje, ale nie było zauważalnego skrócenia całkowitego czasu usuwania w porównaniu do pojedynczej operacji usuwania. I chociaż tworzenie list usuwania może być niepożądane, zaoszczędzony czas był tego wart.

@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

Spróbuj tego i zmodyfikuj w razie potrzeby.

Jest to przetestowany skrypt na Win2003 na podstawie Synetech za wyjaśnienie techniczne i Analiza odpowiedziało 15 października '13 na 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 .. Istnieją foldery takie jak A1 do A4, B1 do B4 i C1 do C4 zagnieżdżone inaczej ..

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>

Nie mogę komentować (strona narzeka na moją reputację), więc dodaję tutaj swój komentarz ..

Rozwiązanie Bjv tworzy bezużyteczne tymczasowe listy plików. A następnie powtarza je po raz drugi, aby wykonać rzeczywistą pracę. /superuser//a/892412/528695

Oryginalny skrypt Synetecha nie działał dla mnie. /superuser//a/416469/528695

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

Wyniki ..

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>

Mogę sprawdzić, czy @ user4350129 jest poprawny, gdy mówi, że skrypt Synetecha nie działa - miałem takie samo zachowanie na moim polu Win7x64.
leinad13

Cholera, mój skrypt też nie był doskonały, problemy z brakiem argumentu i przepełnieniem cytatu przerwały komendy anc icacls .. również sprawdziłem tylko foldery, a nie pliki .. Naprawiłem te problemy ... edytowałem post, ale zawsze testuj przed użyciem.
EO

2

Miałem podobne problemy dawno temu z zaledwie 10 milionami plików, ale na serwerze 2003, aby je usunąć, użyłem serwera / klienta ftp i zostawiłem klienta usuwając pliki i foldery. To powolne rozwiązanie, ale działa idealnie.

Prawdopodobnie będziesz miał drugi problem z MFT w NTFS, który nie ma rozwiązania, MFT to tablica, która w Windows 2003 (nie jestem pewien, czy Microsoft ma rozwiązanie po Windows 2003) przechowuje wszystkie pliki przyrostowo, więc z bilionem plików rozmiar będzie szalony, w moim przypadku MFT miał 17 milionów rekordów, a rozmiar MFT wynosił około 19 GB z zaledwie 45000 plików, testowałem w innych systemach i wygląda na 1 milion rekordów, które MFT będzie być około 1 GB.

Możesz sprawdzić status MFT za pomocą tego polecenia:

defrag C: /a /v
  • C: - litera jednostkowa
  • /a - analizować
  • /v - gadatliwy

Kolejne trudne rozwiązanie, ponieważ nie ma narzędzia, które mogłoby zmniejszyć MFT, narzędzia po prostu wypełniają 0 nazwą plików i właściwości, ale nic więcej, ale możesz użyć konwertera VMware lub innego rodzaju P2V i stworzyć maszynę wirtualną na podstawie twój serwer, w ten sposób naprawisz wszystkie problemy związane z MFT, nigdy nie testowałem konwersji z V2P, teraz pracuję tylko w środowiskach wirtualnych, ale widziałem wiele informacji na ten temat w Internecie.

Ta wygrana w 2003 roku działa teraz doskonale, rozmiar MFT wynosi 40 MB i wszystko jest w porządku, jeśli chcesz, mogę powiedzieć ci więcej o kopiach zapasowych, defragmentacjach lub innych zadaniach związanych z milionami małych plików.



1

Ponieważ usuwanie wszystkich plików jednocześnie zajmuje zbyt dużo pamięci, potrzebujesz sposobu, aby je usunąć pojedynczo, ale z automatycznym procesem. Tego typu rzeczy są o wiele łatwiejsze do wykonania w powłoce uniksowej, więc użyjmy Cygwina. Poniższe polecenie generuje listę zwykłych plików, przekształca tę listę w sekwencję rmpoleceń, a następnie podaje wynikowy skrypt do powłoki.

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

Skrypt jest wykonywany nawet podczas generowania i nie ma żadnych pętli, więc powłoka nie musi (miejmy nadzieję) tworzyć żadnych dużych plików tymczasowych. To na pewno zajmie trochę czasu, ponieważ skrypt ma miliony linii. Być może będziesz musiał dostosować rmpolecenie (być może powinienem był użyć-f ale rozumiesz swoje pliki lepiej niż ja), aby działało.

Teraz nie masz już nic oprócz katalogów. Oto, gdzie robi się brudno. Być może usunąłeś wystarczającą liczbę plików, abyś mógł zrobić to rm -rfbez braku pamięci (i prawdopodobnie będzie to szybsze niż inny skrypt). Jeśli nie, możemy dostosować odpowiedź Stackoverflow :

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

Ponownie, poprawianie może być konieczne, tym razem z sort, aby uniknąć tworzenia dużych plików tymczasowych.


1

Natknąłem się na ten sam problem jakiś czas temu. Napisałem małe narzędzie, które robi dokładnie to: rekurencyjnie usuwa katalog. Nie będzie wyliczał plików i nie zużywa dużo pamięci (O (n + m) na maksimum przy n = maksymalna głębokość katalogu i m = maksymalna liczba plików / katalogów w jednym z podkatalogów). Może obsługiwać długie ścieżki plików (> 256 znaków). Chciałbym uzyskać informację zwrotną, jeśli możesz rozwiązać ten problem.

Można go znaleźć tutaj: https://github.com/McNetic/fdeltree (plik wykonywalny w folderze wydań)


1

Znalazłem ten wątek, który szuka lepszego sposobu niż usunięcie ponad 3 milionów plików na kilku obsługiwanych serwerach. Powyższe są o wiele bardziej skomplikowane niż IMO, więc skończyłem na mojej znanej metodzie korzystania z narzędzia wiersza polecenia „FORFILES” w systemie Windows (było to na serwerze 2003).

W każdym razie poniżej znajduje się polecenie FORFILES, którego użyłem do usunięcia WSZYSTKICH plików w folderze z wiersza polecenia.

forfiles / P „TWOJA FOLDEROWA ŚCIEŻKA TUTAJ (np. C: \ Windows \ Temp)” / C ”cmd / c echo @file & del / f / q @file”

Powyższe również ECHO to nazwa plików, które są usuwane na ekran, ale tylko dlatego, że chciałem zobaczyć pewien postęp w tym, że faktycznie coś robi, jeśli nie powtórzysz czegoś, wygląda to tak, jakby okno DOS zawiesiło się, nawet choć działa zgodnie z oczekiwaniami.

Inicjacja zajmuje trochę czasu, tzn. Wygląda na to, że przez jakiś czas nic nie robi (około 30m dla ~ 3 milionów plików), ale ostatecznie powinieneś zobaczyć, jak nazwy plików zaczynają się pojawiać po ich usunięciu. Ta metoda zajmuje również dużo czasu, aby usunąć pliki (czas usuwania może być zostać skrócony bez echa?), Ale ostatecznie działa bez awarii komputera, na moich serwerach pliki używały ~ 1850 KB pamięci podczas procesu usuwania. .

Czas trwania usuwania może powodować problem, jeśli twoje serwery mają automatyczne wylogowanie, ponieważ musisz utrzymać mysz w ruchu (zaleciłbym uruchomienie jako użytkownik konsoli lub za pomocą narzędzia trzeciej części, takiego jak LanDesk lub SCCM itp. (Lub MouseJiggle). exe))

W każdym razie, pomyślałem, że podzielę się moją odpowiedzią, powodzenia wszystkim!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.