Irgendwie hat eine unserer alten Server 2008-Boxen (nicht R2) einen scheinbar unendlich rekursiven Ordner entwickelt. Dies spielt bei unseren Backups eine große Rolle, da der Backup-Agent versucht, in den Ordner zurückzukehren, und niemals zurückkehrt.
Die Ordnerstruktur sieht ungefähr so aus:
C:\Storage\Folder1
C:\Storage\Folder1\Folder1
C:\Storage\Folder1\Folder1\Folder1
C:\Storage\Folder1\Folder1\Folder1\Folder1
... und so weiter. Es ist wie eines dieser Mandelbrot-Sets, mit denen wir alle in den 90ern gespielt haben.
Ich habe es versucht:
- Löschen Sie es aus dem Explorer. Ja, ich bin ein Optimist.
RMDIR C:\Storage\Folder1 /Q/S
- das kehrt zurückThe directory is not empty
ROBOCOPY C:\temp\EmptyDirectory C:\Storage\Folder1 /PURGE
- Dies dreht sich einige Minuten lang durch die Ordner, bevor robocopy.exe abstürzt.
Kann jemand einen Weg vorschlagen, um diesen Ordner endgültig zu löschen?
/MIR
stattdessen versuchen :ROBOCOPY /MIR C:\temp\EmptyDirectory C:\Storage\Folder1
Vielleicht lohnt es sich auch,chkdsk
nur für ein Kichern zu laufen ./MIR
schien länger zu dauern, wurde aber schließlich auch bombardiert ("Robocopy hat aufgehört zu funktionieren"). Ich habe ein bisschen Angst ein zu tunchkdsk
; Dies ist ein ziemlich alter Server und ich mache mir Sorgen, dass dieses Problem auf größere Dateisystemprobleme hinweist ...find
Sie eine erste Tiefenentfernung des Verzeichnisses durchführen:find Storage/Folder1 -depth -exec rmdir {} \;
Antworten:
Vielen Dank an alle für den nützlichen Rat.
Auf dem Weg nach StackOverflow habe ich das Problem gelöst, indem ich dieses C # -Code-Snippet in die Knie gezwungen habe. Es verwendet die Delimon.Win32.IO- Bibliothek, die speziell Probleme beim Zugriff auf lange Dateipfade behebt .
Nur für den Fall, dass dies jemand anderem helfen kann, hier ist der Code - er hat die ~ 1600 Rekursionsebenen durchlaufen, mit denen ich irgendwie festgefahren war, und es dauerte ungefähr 20 Minuten, um sie alle zu entfernen.
quelle
.Delete
(anstelle der normalenSystem.IO
Version), und obwohl es keine Ausnahme warf, schien es nichts zu tun. Sicherlich dauerte die Rekursion mit der oben beschriebenen Methode eine Ewigkeit und dauerte.Delete
nur 5-10 Sekunden. Vielleicht hat es ein paar Verzeichnisse weggeschlagen und dann aufgegeben?Könnte ein rekursiver Knotenpunkt sein. So etwas kann mit
junction
einem Datei- und Festplatten-Dienstprogramm von Sysinternals erstellt werden .Und jetzt können Sie endlos nach unten gehen: c: \ Hello \ Hello \ Hello .... (nun, bis MAX_PATH erreicht ist, 260 Zeichen für die meisten Befehle, aber 32.767 Zeichen für einige Windows-API-Funktionen).
Eine Verzeichnisliste zeigt, dass es sich um eine Junction handelt:
Verwenden Sie zum Löschen das Junction-Dienstprogramm:
quelle
DIR
zeigt mir eine nur einfache alte Verzeichnisse - keine Anzeichen von Kreuzungen fürchte ichjunction -s C:\Storage\Folder1
?No reparse points found
:(dir /a
, um '<JUNCTION>' anzuzeigen, ohne den spezifischen Namen anzugeben.Keine Antwort, aber ich habe nicht genug Repräsentanten für einen Kommentar.
Ich habe dieses Problem einmal auf einer damals riesigen 500-MB-FAT16-Disk auf einem MS-DOS-System behoben. Ich habe DOS-Debug verwendet, um die Verzeichnistabelle manuell auszugeben und zu analysieren. Ich habe dann ein Bit umgedreht, um das rekursive Verzeichnis als gelöscht zu markieren. Mein Exemplar von Dettman und Wyatt 'DOS Programmers' Reference 'zeigte mir den Weg.
Darauf bin ich immer noch außerordentlich stolz. Ich wäre erstaunt und verängstigt, wenn es ein Allzweck-Tool geben würde, das über eine solche Leistung für FAT32- oder NTFS-Volumes verfügt. Das Leben war damals einfacher.
quelle
Java kann auch mit langen Dateipfaden umgehen. Und es geht auch viel schneller. Dieser Code (den ich aus der Java-API-Dokumentation kopiert habe) löscht eine Verzeichnisstruktur mit 1600 Ebenen in ungefähr 1 Sekunde (unter Windows 7, Java 8.0) und ohne das Risiko eines Stapelüberlaufs, da keine Rekursion verwendet wird.
quelle
Sie benötigen keine langen Pfadnamen, wenn Sie
chdir
sich im Verzeichnis befinden und nur relative Pfade zu verwendenrmdir
.Oder wenn Sie eine POSIX-Shell installiert haben oder diese auf das DOS-Äquivalent portieren:
(Die Verwendung einer Shell-Variablen zum Verfolgen, wo Sie sie für die Schleifenbedingung umbenannt haben, ist die andere Alternative zum Aufrollen der Schleife, wie ich es dort getan habe.)
Dies vermeidet den CPU-Overhead der KenD-Lösung, der das Betriebssystem dazu zwingt, den Baum
n
jedes Mal von oben nach unten zu durchlaufen, wenn eine neue Ebene hinzugefügt wird, Berechtigungen überprüft usw. Das hat alsosum(1, n) = n * (n-1) / 2 = O(n^2)
zeitliche Komplexität. Lösungen, die von Anfang an einen Teil der Kette abtrennenO(n)
, sollten es sein , es sei denn, Windows muss beim Umbenennen des übergeordneten Verzeichnisses einen Baum durchlaufen. (Linux / Unix nicht.) Lösungen,chdir
die sich bis zum Ende des Baums erstrecken und von dort aus relative Pfade verwenden und Verzeichnisse beim Sichern entfernenchdir
, sollten auchO(n)
funktionieren, vorausgesetzt, das Betriebssystem muss nicht alle Ihre Pfade überprüfen Übergeordnete Verzeichnisse bei jedem Systemaufruf, wenn Sie Dinge erledigen, während Sie sich auf einer CD befinden.find Folder1 -depth -execdir rmdir {} +
wird rmdir ausführen, während die CD in das tiefste Verzeichnis verschoben wird. Oder tatsächlich-delete
funktioniert finds Option für Verzeichnisse und impliziert-depth
. Alsofind Folder1 -delete
sollte genau das Gleiche tun, aber schneller. Ja, GNU find unter Linux wird durch Durchsuchen eines Verzeichnisses ausgeführt und in Unterverzeichnisse mit relativen Pfaden und dannrmdir
mit relativen Pfaden kopiertchdir("..")
. Während des Aufstiegs werden keine Verzeichnisse erneut durchsucht, sodassO(n)
RAM verbraucht wird .Das war wirklich eine Annäherung:
strace
zeigt, dass es WIRKLICH verwendetunlinkat(AT_FDCWD, "tmp", AT_REMOVEDIR)
wirdopen("..", O_DIRECTORY|...)
, undfchdir(the fd from opening the directory)
mit ein paarfstat
Gesprächen auch. Der Effekt ist jedoch der gleiche, wenn der Verzeichnisbaum während der Ausführung von find nicht geändert wird.Bearbeiten: Nur zum Spaß habe ich dies unter GNU / Linux versucht (Ubuntu 14.10, auf einer Core2Duo-CPU der ersten Generation mit 2,4 GHz, auf einem XFS-Dateisystem auf einem WD 2,5 TB Green Power-Laufwerk (WD25EZRS)).
(mkdir -p erstellt ein Verzeichnis und alle fehlenden Pfadkomponenten).
Ja, wirklich 0,05 Sekunden für 2k rmdir ops. xfs ist ziemlich gut darin, Metadatenoperationen im Journal zusammenzufassen, da es feststellte, dass Metadatenoperationen wie vor 10 Jahren langsam waren.
Auf ext4 hat das Erstellen 0m0.279s gedauert, das Löschen mit find hat noch 0m0.074s gedauert.
quelle
Ich bin auf dasselbe Problem gestoßen, bei dem es um mehr als 5000 verzeichnisintensive Ordner ging, wie bei einigen Java-Anwendungen, und ich habe ein Programm geschrieben, mit dem Sie diesen Ordner entfernen können. Der gesamte Quellcode befindet sich in diesem Link:
https://imanolbarba.net/gitlab/imanol/DiREKT
Es hat das Ganze nach einer Weile entfernt, aber es hat es geschafft, die Arbeit zu erledigen. Ich hoffe, es hilft Menschen, die (wie ich) auf dasselbe frustrierende Problem stoßen
quelle
Ich hatte dies auch auf einem eigenständigen Windows 10-System. C: \ Benutzer \ Name \ Wiederholen \ Wiederholen \ Wiederholen \ Wiederholen \ Wiederholen \ Wiederholen \ Wiederholen scheinbar unendlich.
Ich konnte mit Windows oder der Eingabeaufforderung zum 50. navigieren und nicht weiter. Ich konnte es nicht löschen oder darauf klicken usw.
C ist meine Sprache, also habe ich schließlich ein Programm mit einer Schleife von Systemaufrufen geschrieben, die sich wiederholen, bis sie fehlschlagen. Sie können dies jedoch in jeder Sprache tun, auch im DOS-Batch. Ich habe ein Verzeichnis mit dem Namen tmp erstellt und Repeat \ Repeat in dieses Verzeichnis verschoben, den jetzt leeren Repeat-Ordner gelöscht und tmp \ Repeat wieder in den aktuellen Ordner verschoben. Wieder und wieder!
ChkSystem führt nur einen system () -Aufruf aus und überprüft den Rückgabewert.
Es ist wichtig, dass es einige Male fehlgeschlagen ist. Ich dachte, mein Programm würde vielleicht nicht funktionieren oder es wäre unendlich lange her. Ich hatte dies jedoch schon einmal mit Systemaufrufen, bei denen die Dinge nicht synchronisiert wurden. Deshalb habe ich das Programm erneut ausgeführt und es wurde an der Stelle fortgesetzt, an der es aufgehört hat. Denken Sie also nicht sofort, dass Ihr Programm nicht funktioniert. Insgesamt löschte es sie alle, nachdem es ungefähr 20 Mal ausgeführt worden war. Insgesamt waren es ursprünglich ungefähr 1280 Ordner. Keine Ahnung woran es liegt. Verrückt.
quelle