So löschen Sie eine große Anzahl von Dateien unter Windows

22

Ich habe ein Verzeichnis, das Millionen von Unterverzeichnissen und Billionen von Dateien enthält. Und jetzt muss ich es klären. Ich spreche nicht von der Dateigröße, sondern von der Anzahl der Dateien.

Ich habe versucht, es mit zu löschen del/sund Windows Explorer zu verwenden. Keiner kann die Aufgabe abschließen. Ich habe versucht, einige der Unterverzeichnisse einzeln zu löschen, und das hat Tage gedauert. Das Problem, auf das ich gestoßen bin, war, dass delich im Task-Manager jedes Mal, unabhängig von der Verwendung von oder dem Explorer, feststellen kann, dass die Explorer-Instanz himmelhohen Speicher belegt und mein System nach und nach zum Absturz bringt.

Es müssen noch einige hundert Millionen Dateien gelöscht werden. Gibt es eine Möglichkeit, mit einem (oder wenigen) Befehlen / Aktionen etwas zu erreichen?


[EDITED]

Ich habe es mit Cygwin rm -frversucht und das gleiche Ergebnis erzielt . Zusammengefasst als:

  1. DELUnabhängig davon, ob Sie den Windows Explorer über die Eingabeaufforderung oder den Cygwin- rmBefehl verwenden, wird der Systemspeicher allmählich auf Null reduziert und die Box stürzt schließlich ab.

  2. Wenn zu irgendeinem Zeitpunkt, bevor das System ausfällt, der Prozess geschlossen wird (mit STRG + C oder was sonst), funktioniert die Box wie gewohnt weiter. Der gesamte verwendete Speicher wird jedoch NICHT freigegeben. Angenommen, ich habe den Prozess angehalten, während der Systemspeicher 91% erreicht. Der Task-Manager gibt an: 4 GB RAM insgesamt, der Cache 329 MB und die verfügbare Kapazität 335 MB. Dann bleibt die Speichernutzung auf diesem Niveau, bis ich den Computer neu starte. Wenn ich die Explorer-Instanz im Task-Manager stoppe, wird der Bildschirm bei eingeschalteter Festplattenanzeige immer dunkel und kommt nie wieder. Normalerweise kann ich die Explorer-Instanz im Task-Manager durch Drücken von Win + E erneut aufrufen oder sie wurde automatisch neu gestartet.

Na ja, wirklich schönes Speichermanagement!


[WIEDER BEARBEITEN] Es scheint, dass ein Teil des verwendeten Speichers nach einer langen Zeit freigegeben wurde, aber nicht alle. Ein Teil des zwischengespeicherten und verfügbaren Speichers wurde im Task-Manager wiederhergestellt. Ich habe nicht länger gewartet und bin mir nicht sicher, was dann passieren wird.

Jackey Cheung
quelle
Ihr Hauptproblem ist also die Tatsache, dass Verzeichnisse und Unterverzeichnisse nicht gelöscht werden?
Sandeep Bansal
@ Jackey Cheung: Welche Version von Windows verwenden Sie?
Siva Charan
1
Sie könnten ein Stapelskript schreiben, das Dateien rekursiv löscht, und zwar nicht von der obersten Ebene aus, sondern z. B. auf der fünften Ebene der Ordnerstruktur. Das würde den Job in viele separate und sequentielle
9
Ich muss wissen, wie zum Teufel hast du wirklich Billionen Akten bekommen ...
Moab
2
Eine Billion Dateien benötigen eine Dateitabelle von 1 PB. Die größten Festplatten sind heutzutage einige TB. Wie haben Sie möglicherweise eine so große Partition bekommen?
Mehrdad

Antworten:

10

Technische Erklärung

Die meisten Methoden verursachen Probleme, weil Windows versucht, die Dateien und Ordner aufzulisten. Bei ein paar hundert oder sogar tausend Dateien / Ordnern mit einer Tiefe von einigen Ebenen ist dies kein großes Problem. Wenn Sie jedoch Billionen von Dateien in Millionen von Ordnern haben, die Dutzende von Ebenen tief gehen, wird dies das System definitiv zum Erliegen bringen .

Sie haben "nur" 100.000.000 Dateien, und Windows verwendet eine einfache Struktur wie diese, um jede Datei zusammen mit ihrem Pfad zu speichern.

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
}

Abhängig davon, ob 8-Bit-Zeichen oder Unicode-Zeichen (Unicode) verwendet werden und ob Ihr System 32-Bit- oder 64-Bit-Speicher ist, werden zwischen 25 GB und 49 GB Arbeitsspeicher zum Speichern der Liste benötigt (und dies ist sehr wichtig) vereinfachte Struktur).

Der Grund, warum Windows versucht, die Dateien und Ordner vor dem Löschen aufzulisten, hängt von der Methode ab, mit der Sie sie löschen. Dies geschieht jedoch sowohl im Explorer als auch im Befehlsinterpreter (es kann eine Verzögerung auftreten, wenn Sie den Befehl einleiten). Sie können auch sehen, wie die Festplattenaktivität (HDD-LED) blinkt, während der Verzeichnisbaum vom Laufwerk gelesen wird.

Lösung

In solchen Situationen sollten Sie am besten ein Löschtool verwenden, das die Dateien und Ordner einzeln nacheinander löscht. Ich weiß nicht, ob es dafür fertige Tools gibt, aber es sollte möglich sein, dies mit einer einfachen Batch-Datei zu erreichen.

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

Dies überprüft, ob ein Argument übergeben wurde. In diesem Fall wechselt es in das angegebene Verzeichnis (Sie können es ohne Argument ausführen, um im aktuellen Verzeichnis zu starten, oder ein Verzeichnis angeben - auch auf einem anderen Laufwerk, damit es dort startet).

Als nächstes werden alle Dateien im aktuellen Verzeichnis gelöscht. In diesem Modus sollte es nichts aufzählen und die Dateien einfach löschen, ohne viel, wenn überhaupt, Speicherplatz in Anspruch zu nehmen.

Dann zählt es die Ordner im aktuellen Verzeichnis auf und ruft sich selbst auf, wobei es jeden Ordner an sich selbst weiterleitet, um abwärts zu rekursieren.

Analyse

Der Grund, warum dies funktionieren sollte , ist, dass nicht jede einzelne Datei und jeder einzelne Ordner in der gesamten Struktur aufgelistet wird . Es werden überhaupt keine Dateien aufgelistet und nur die Ordner im aktuellen Verzeichnis (sowie die übrigen in den übergeordneten Verzeichnissen). Angenommen, es gibt nur ein paar hundert Unterverzeichnisse in einem bestimmten Ordner, dann sollte dies nicht allzu schlimm sein und mit Sicherheit viel weniger Speicher als bei anderen Methoden, die den gesamten Baum auflisten.

Möglicherweise möchten Sie den /rSchalter anstelle der (manuellen) Rekursion verwenden. Das würde nicht funktionieren, da der /rSwitch zwar eine Rekursion durchführt, aber den gesamten Verzeichnisbaum vorab auflistet, was genau das ist, was wir vermeiden wollen. Wir möchten löschen, ohne den Überblick zu behalten.

Vergleich

Vergleichen wir diese Methode mit der (den) Methode (n) mit vollständiger Aufzählung.

Sie hatten gesagt, Sie hätten "Millionen von Verzeichnissen"; Sagen wir 100 Millionen. Wenn der Baum ungefähr ausgeglichen ist und ein Durchschnitt von etwa 100 Unterverzeichnissen pro Ordner angenommen wird, wäre das tiefste verschachtelte Verzeichnis etwa vier Ebenen tiefer - tatsächlich gibt es 101.010.100 Unterverzeichnisse im gesamten Baum. (Amüsant, wie 100M auf nur 100 und 4 herunterbrechen können.)

Da wir keine Dateien auflisten, müssen wir nur maximal 100 Verzeichnisnamen pro Ebene für maximal 4 × 100 = 400Verzeichnisse zu einem bestimmten Zeitpunkt nachverfolgen.

Aus diesem Grund sollte der Speicherbedarf ~ 206,25 KB betragen und innerhalb der Grenzen eines modernen (oder anderen) Systems liegen.

Prüfung

Leider (?) Habe ich kein System mit Billionen von Dateien in Millionen von Ordnern, daher kann ich es nicht testen (ich glaube, zuletzt hatte ich ungefähr 800.000 Dateien), also muss es jemand anderes versuchen es.

Vorbehalt

Natürlich ist der Speicher nicht die einzige Einschränkung. Das Laufwerk stellt auch einen großen Engpass dar, da das System für jede gelöschte Datei und jeden Ordner diese als frei markieren muss. Zum Glück werden viele dieser Festplattenvorgänge gebündelt (zwischengespeichert) und nicht einzeln, sondern in Blöcken geschrieben (zumindest für Festplatten, nicht für Wechselmedien), aber es wird immer noch einiges an Thrashing verursachen, während das System liest und schreibt die Daten.

Synetech
quelle
Ich bin mir ziemlich sicher, dass das nicht funktioniert. Ich habe es versucht. Das Problem liegt in der FOR-Schleife. Es stellte sich heraus, dass die FOR das gleiche Problem verursacht wie die direkte Ausgabe von DEL.
Jackey Cheung
1
Dies hängt von den verwendeten Schaltern ab. Wenn Sie den /rSchalter verwendet haben, wird er, wie bereits erläutert, versuchen, alle Dateien aufzulisten. Wenn Sie den /dSchalter verwenden, werden nur die Ordner im aktuellen Verzeichnis aufgelistet. Wenn Sie also nicht über eine Milliarde Ordner im aktuellen Verzeichnis verfügen, sollte dies kein Problem verursachen.
Synetech
7

Ich kann nicht mit den Billionen von Dateien sprechen, aber ich habe kürzlich eine alte Dateifreigabe mit ~ 1,8 Millionen Dateien überarbeitet:

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

"EmptyTMPFolder" ist ein leeres lokales Verzeichnis. Mit der Option / MIR sieht das Ziel wie die Quelle aus (leer).

Der eigentliche Vorteil dieses Ansatzes war die Wiederholungsoption (/ R: 30). Dies ermöglichte die Übernahme von Verbindungsproblemen, die während dieses Vorgangs auftreten können. Lokale Löschvorgänge haben bei diesem Ansatz möglicherweise keinen Nutzen.

Ich habe keine spezifischen Benchmarks, um die Zeiten zu vergleichen, aber ich würde dies einigen anderen Optionen vorziehen, die in den Optionen zum erneuten Versuch / Warten vorgeschlagen werden. Die Löschvorgänge begannen fast augenblicklich.

matt.bungard
quelle
Ich fand, dass dies bei weitem die effizienteste Methode ist, wenn die Bereinigung auf einem großen Netzwerklaufwerk-Ordnerbaum ausgeführt wird. Danke für den Tipp.
Tonny
5

Das Löschen aller Ordner nimmt viel Zeit in Anspruch, und Sie können nicht viel dagegen tun. Sie können Ihre Daten speichern und Ihr Laufwerk formatieren. Es ist nicht optimal, aber es wird funktionieren (und zwar schnell).

Eine andere Möglichkeit ist vielleicht die Verwendung einer Linux-Distribution auf einer Live-CD, die von einer NTFS-Partition lesen kann. Ich weiß aus eigener Erfahrung, dass rm -rf folderNamemindestens 2 Tage ausgeführt werden können, ohne ein System mit 2 GB RAM zum Absturz zu bringen. Es wird eine Weile dauern, aber zumindest wird es enden.

soandos
quelle
1
hm, Linux. Ich denke an den Cygwin. Es wird vorausgesetzt, dass Sie unterstreichende Windows-Funktionen verwenden, fragen Sie sich jedoch, ob dies einen Unterschied in diesem Fall bewirken wird. Ich werde es ausprobieren.
Jackey Cheung
1
Sie können Git Bash
Regentropfen
4

Ähm ... ich will nicht wissen, wie du so viele erschaffen hast.

Der Explorer versucht, jede einzelne Datei aufzulisten und die Informationen im Speicher zu speichern, bevor sie gelöscht werden. Und es gibt offensichtlich viel zu viele.

Hast du den Befehl ausprobiert rmdir /s? Solange die gefundenen Dateien tatsächlich gelöscht werden und nicht auf jede einzelne Aufzählung gewartet wird, funktioniert dies möglicherweise.

Wie viele Unterverzeichnisse gibt es? Wenn es nur eine oder eine andere niedrige Zahl gibt, funktioniert möglicherweise eine schnelle Batch-Datei, die manuell durchlaufen wird.

Jede Methode wird jedoch eine Weile dauern.

Bob
quelle
Abgesehen von Soandos Vorschlag zur Neuformatierung natürlich. Das wäre schnell, aber wenn dies Ihr Systemlaufwerk ist, müssen Sie Windows neu installieren.
Bob
Ich bin mir ziemlich sicher, dass die Aufzählung stattfinden muss, nur damit das Programm weiß, was als nächstes zu löschen ist. rmdir kann keine Dateien löschen, wenn sie gefunden werden, da es von oben beginnt und irgendwie durchlaufen werden muss. Die Frage ist nur, wie viel überschüssige Informationen gespeichert werden.
Soandos
@soandos Explorer zählt jede Datei. Ich dachte an eine Methode, die einen DFS-Aufzählungsstil implementiert: Gehen Sie so weit wie möglich durch einen Zweig, und löschen Sie ihn, wenn er auf eine Datei stößt, bevor Sie wieder auftauchen. Mit anderen Worten: Rekursion rm -rf. Das funktioniert am besten mit relativ flachen Verzeichnisstrukturen. Ich bin mir nicht sicher, ob rmdir /sdas so ist. Es sollte .
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.Mit anderen Worten, das /sFlag entfernt auch Dateien. Wie hast du benutzt del? Und ja, es könnte besser sein, es einfach so zu verwenden, rm -rfwie es die anderen vorgeschlagen haben.
Bob
1
@ JackeyCheung: Du liegst falsch. Wenn Sie rmdir das Flag / s geben, werden sowohl Dateien als auch Verzeichnisse gelöscht.
Harry Johnston
4

Eine mögliche Ursache für ein solches Problem ist die Thin-Bereitstellung, die normalerweise in SAN-Umgebungen auftritt. Einige Solid-State-Laufwerke weisen möglicherweise dasselbe Problem auf. In diesem Fall könnte diese Konfigurationsänderung Ihr Problem lösen:

fsutil behavior set DisableDeleteNotify 1

Beachten Sie, dass diese Änderung die Leistung von Solid-State-Laufwerken beeinträchtigen und ein automatisches und / oder manuelles Überdenken von SAN-Laufwerken verhindern kann.

Harry Johnston
quelle
3

Shift+ Deleteüberspringt den Papierkorb und beschleunigt möglicherweise die Arbeit erheblich.

Wenn dies nicht funktioniert (Extremfälle), versuchen Sie es mit Fast Folder Eraser und / oder Mass Directory Eraser

Tamara Wijsman
quelle
Als ich versucht habe, eine große Anzahl von Bilddateien zu löschen, ist Shift DEL im Vergleich zu normalem DEL ziemlich schnell, danke
V-SHY
3

Wahrscheinlich verbraucht Ihre Antiviren- / Antimalware den gesamten Speicher und stürzt dann das System ab.

Windows selbst hat kein Problem damit, eine große Anzahl von Dateien zu löschen, obwohl dies auf den meisten Nicht-Microsoft-Dateisystemen langsamer ist als ein ähnlicher Vorgang.

Ben Voigt
quelle
Schöner Punkt! Sicher einen Blick wert.
Jackey Cheung
Ich habe Antivirus deaktiviert, und der Speicher wurde weiterhin wie zuvor aufgebraucht.
Jackey Cheung
Das Deaktivieren von Antivirus hilft auch nicht dabei, Speicher freizugeben, nachdem der Prozess angehalten wurde.
Jackey Cheung
@ JackeyCheung: Um welches Antivirenprogramm handelt es sich? Einige schalten sich tatsächlich nicht vollständig aus ...
Ben Voigt
2

Ein Problem, auf das Sie möglicherweise stoßen, besteht darin, dass das Verzeichnis beim Löschen einer Datei / eines Ordners nicht komprimiert wird. Wenn Sie also einen Ordner mit 1 Million Dateien haben und die ersten 500.000 Dateien löschen, wird der Ordner möglicherweise nicht komprimiert. Es gibt eine Menge Blöcke am Anfang Ihres Verzeichnisses, die für alle Fälle leer sind.

ABER der Explorer und eine Eingabeaufforderung müssen diese Blöcke noch durchsuchen, nur für den Fall, dass dort eine Datei vorhanden ist. Etwas, das helfen könnte, ist, einen Ordner von irgendwo in der Baumstruktur in einen neuen Ordner von der Basis des Laufwerks zu "verschieben" und dann diesen neuen Ordner zu löschen. Durch das Verschieben des Ordners wird nur der Zeiger auf den Ordner verschoben, sodass dieser schnell verschoben werden kann und nicht alle Dateien auf dem Laufwerk an einen neuen Speicherplatz verschoben werden.

Sie können auch versuchen, ein Drittanbieter-Tool wie "PerfectDisk" zum Komprimieren von Ordnern nach dem Löschen einer Reihe von Dateien zu verwenden.

Kelly
quelle
2

Beim Versuch, über 10 Millionen Fusionsprotokolldateien auf verschiedene Weise zu löschen, stellte ich fest, dass durchschnittlich 30.000 Dateien innerhalb von 10 Minuten gelöscht werden konnten. Das würde ungefähr 55 Stunden für die 10 Millionen Dateien dauern ...

Mit dem folgenden Skript wurde die Löschrate um ~ 75% erhöht. Dateilisten werden durch gleichzeitige Prozesse erstellt und ausgeführt, wodurch die Datenträgeroperationen erhöht werden (aber nicht linear). Ich zeige 4 Gabeln, aber zwei könnten ausreichen.

Es besteht die Möglichkeit, PowerShell zu verwenden, wodurch sich der Zeitaufwand für die Erstellung der Listen erheblich verringert.

Übrigens habe ich zwei direkte Löschoperationen getestet, die Kollisionen zulassen, aber es gab keine merkliche Verringerung der Gesamtlöschzeit im Vergleich zu einer einzelnen Löschoperation. Und obwohl es möglicherweise nicht wünschenswert ist, Löschlisten zu erstellen, hat sich die Zeitersparnis gelohnt.

@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
bvj
quelle
2

Probieren Sie dies aus und ändern Sie es nach Bedarf.

Es handelt sich um ein getestetes Skript für Win2003, das auf Synetechs technischer Erklärung und Analyse basiert und am 15. Oktober 13 um 15:22 Uhr beantwortet wurde

@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%"

Testlauf .. Es sind Ordner wie A1 bis A4, B1 bis B4 und C1 bis C4 unterschiedlich verschachtelt ..

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>

Ich kann keinen Kommentar abgeben (Website beschwert sich über meinen Ruf), daher füge ich meinen Kommentar hier hinzu.

Bjvs Lösung erstellt nutzlose temporäre Dateilisten. Und wiederholt sie dann zum zweiten Mal, um die eigentliche Arbeit zu erledigen. /superuser//a/892412/528695

Das ursprüngliche Skript von Synetech hat bei mir nicht funktioniert. /superuser//a/416469/528695

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

Ergebnisse..

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>
EO
quelle
Ich kann überprüfen, ob @ user4350129 korrekt ist, wenn er sagt, dass das Skript von Synetech nicht funktioniert - ich hatte das gleiche Verhalten auf meiner Win7x64-Box.
leinad13
Verdammt, mein Skript war auch nicht perfekt, Probleme mit fehlenden Argumenten und Anführungszeichen brachen übernommene Anc icacls-Befehle. Außerdem habe ich nur Ordner und keine Dateien überprüft. Ich habe diese Probleme behoben. Nachbearbeitet, aber immer vor der Verwendung getestet.
EO
2

Ich hatte vor einiger Zeit ähnliche Probleme mit nur 10 Millionen Dateien, aber in einem Server 2003, um die Dateien zu löschen, benutzte ich einen FTP-Server / Client und ließ den Client die Dateien und Ordner löschen. Es ist eine langsame Lösung, aber es funktioniert perfekt.

Wahrscheinlich haben Sie ein zweites Problem mit der MFT in NTFS, das keine Lösung hat. Die MFT ist ein Array, das in Windows 2003 (ich bin nicht sicher, ob Microsoft nach Windows 2003 eine Lösung hat) alle Dateien inkrementell speichert mit Billionen von Dateien wird die Größe verrückt sein, in meinem Fall hatte die MFT 17 Millionen Datensätze und die Größe der MFT lag bei etwa 19 GB mit nur 45000 Dateien, ich habe sie in anderen Systemen getestet und für 1 Million Datensätze sieht die MFT aus etwa 1 GB sein.

Sie können den Status der MFT mit diesem Befehl überprüfen:

defrag C: /a /v
  • C: - Einheitsbrief
  • /a - analysieren
  • /v - ausführlich

Eine andere knifflige Lösung, da es kein Tool gibt, das die MFT verkleinern kann, füllen die Tools nur den Namen der Dateien und Eigenschaften mit 0, aber nichts weiter, sondern Sie können VMware Converter oder eine andere Art von P2V verwenden und eine virtuelle Maschine basierend auf erstellen Ihr Server, auf diese Weise werden Sie alle Probleme im Zusammenhang mit der MFT beheben, ich habe die Konvertierung von V2P nie getestet, jetzt arbeite ich nur in virtuellen Umgebungen, aber ich habe viele Informationen darüber im Internet gesehen.

Dieser Sieg 2003 funktioniert jetzt perfekt, die Größe der MFT beträgt 40 MB und alles ist in Ordnung. Wenn Sie möchten, kann ich Ihnen mehr über Backups, Defragmentierungen oder andere Aufgaben im Zusammenhang mit Millionen winziger Dateien erzählen.

user5286776117878
quelle
1

Per dieser Antwort auf Stackoverflow verwendet eine Kombination aus delund rmdir:

del /f/s/q foldername > nul
rmdir /s/q foldername
Geoff
quelle
Ja, das habe ich schon mal gelesen. Eigentlich hilft es in meinem Fall nicht. Da stürzt der Befehl del definitiv ab.
Jackey Cheung
1

Da das Löschen der Dateien auf einmal zu viel Speicherplatz beansprucht, müssen Sie sie einzeln löschen, wobei der Vorgang jedoch automatisiert wird. Diese Art von Dingen ist in einer Unix-artigen Shell viel einfacher zu machen, also lasst uns Cygwin benutzen. Der folgende Befehl generiert eine Liste der normalen Dateien, wandelt diese Liste in eine Folge von rmBefehlen um und leitet das resultierende Skript an eine Shell weiter.

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

Das Skript wird gerade ausgeführt, während es generiert wird, und es gibt keine Schleifen, sodass die Shell (hoffentlich) keine großen temporären Dateien erstellen muss. Es wird sicherlich eine Weile dauern, da das Skript Millionen von Zeilen lang ist. Möglicherweise müssen Sie den rmBefehl anpassen (vielleicht hätte ich ihn verwenden sollen -f? Aber Sie verstehen Ihre Dateien besser als ich), damit er funktioniert.

Jetzt haben Sie nur noch Verzeichnisse. Hier wird es schwierig. Möglicherweise haben Sie genügend Dateien gelöscht, um rm -rfnicht zu wenig Arbeitsspeicher zu haben (und dies ist wahrscheinlich schneller als ein anderes Skript). Wenn nicht, können wir diese Stackoverflow-Antwort anpassen :

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

Auch diesmal kann eine Optimierung erforderlich sein sort, um die Erstellung großer temporärer Dateien zu vermeiden.

Isaac Rabinovitch
quelle
1

Ich bin vor einiger Zeit auf dasselbe Problem gestoßen. Ich habe ein kleines Hilfsprogramm geschrieben, das genau das macht: ein Verzeichnis rekursiv löschen. Die Dateien werden nicht aufgelistet und es wird nicht viel Speicher verbraucht (O (n + m) bei max mit n = maximale Verzeichnistiefe und m = maximale Datei- / Verzeichnisanzahl in einem der Unterverzeichnisse). Es kann lange Dateipfade (> 256 Zeichen) verarbeiten. Ich würde mich über Feedback freuen, wenn Sie Ihr Problem damit lösen können.

Sie finden es hier: https://github.com/McNetic/fdeltree (ausführbar im Ordner "releases")

Nicolai Ehemann
quelle
1

Ich fand, dass dieser Thread nach einem besseren Weg suchte als ich, um über 3 Millionen Dateien auf mehreren der von mir unterstützten Server zu löschen. Die oben genannten sind viel zu kompliziert, so dass ich meine bekannte Methode der Verwendung des Befehlszeilentools "FORFILES" in Windows (dies war auf Server 2003) verwendet habe.

Im Folgenden ist der Befehl FORFILES aufgeführt, mit dem ich ALLE Dateien in einem Ordner über die Befehlszeile gelöscht habe.

forfiles / P "IHR ORDNERPFAD HIER (zB C: \ Windows \ Temp)" / C "cmd / c echo @datei & del / f / q @datei"

Oben ist auch ECHO der Name der Dateien, die auf dem Bildschirm gelöscht werden, aber nur, weil ich einen Fortschritt sehen wollte, der tatsächlich etwas bewirkt. Wenn Sie etwas nicht wiedergeben, sieht es so aus, als ob die DOS-Box sogar hängen geblieben ist obwohl es die Arbeit OK macht, wie erwartet.

Die Initiierung dauert eine Weile, dh es sieht so aus, als würde eine Weile nichts unternommen (ca. 30 m für ~ 3 Millionen Dateien), aber irgendwann sollten die Dateinamen angezeigt werden, sobald sie gelöscht werden. Das Löschen der Dateien dauert auch sehr lange (die Löschzeit kann sich ohne Echo verkürzen?), Funktioniert aber schließlich, ohne dass der Computer abstürzt. Auf meinem Server verwendeten forfiles während des Löschvorgangs ca. 1.850 KB Speicher. .

Die Dauer des Löschvorgangs kann zu Problemen führen, wenn sich Ihre Server automatisch abmelden, wenn Sie die Maus bewegen müssen (ich würde empfehlen, als Konsolenbenutzer oder über ein Drittanbieter-Tool wie LanDesk oder SCCM usw. (oder MouseJiggle). exe))

Wie auch immer, dachte ich würde meine Antwort teilen, viel Glück alle!

RatMonkey
quelle