[Gelöst] std::filesystem_error bei path > MAX_PATH
-
@Tyrdal sagte in [Gelöst] std::filesystem_error bei path > MAX_PATH:
@Swordfish Wie nimmt man den Python, um in C++ Plattformunabhängig mit Dateien zu arbeiten?
system("python script.py")
-
-
@Tyrdal sagte in [Gelöst] std::filesystem_error bei path > MAX_PATH:
@Finnegan sagte in [Gelöst] std::filesystem_error bei path > MAX_PATH:
@hustbaer @Tyrdal Ist die falsche Stelle meiner Meinung nach. Das Problem ist doch hier anscheinend, dass eine Funktion des Betriebssystems bzw. der C-Runtime nicht 0 zurückgibt. Ich würde vermuten, dass ich z.B. auf Linux mit backslash-separierten Pfaden ein ähnliches Resultat erhalte - womit vielleicht auch einleuchtet, weshalb es eventuell nicht sinnvoll ist, dass irgendwelche Anforderungen an Pfad-Formate Teil des Standards sein sollten, sondern vielleicht doch besser "implementation-defined".
Dann ist es aber weitgehend nutzlos.
Ich denke ich muss meine Ansicht hierzu revidieren: Ich habe mir nicht richtig bewusst gemacht, dass
filesystem::path
eine Abstraktion von Pfaden ist, sonst könnte man schliesslich auch überall Strings verwenden. Wenn ich oben von "Pfad-Formaten" rede, dann meine ich damit natürlich die Strings, mit denen einfilesystem::path
im Konstruktor initialisiert wird. Das ist ein nativer Pfad und sollte m.E. exakt übernommen und nicht irgendwie umgeschrieben werden. D.h.exists(path("<zu langer nativer pfad>"))
soll schon fehlschlagen dürfen. Die Directory-Iteratoren arbeiten allerdings mit derpath
-Abstraktion und hier sehe ich es schon als Aufgabe der Standardbibliothek-Entwickler, das so gut wie möglich zu implementieren. D.h. die internen nativen Pfade, die beim Iterieren erzeugt werden, können schon umgeschrieben werden. Die sinnvollste Lösung ist aber wohl einfach wie erwähntGetFileAttributesExW
zu verwenden.Der Standard sollte allerdings nicht vorschreiben, dass beliebig lange Pfade funktionieren müssen. Das ist schon in Ordnung, wenn das "implementation-defined" ist. Schliesslich soll
filesystem
auch Systeme unterstützen, die das schlichtweg nicht können - z.B. ein Embedded-Projekt mit einem "Flat"-Dateisystem, das nur ein Wurzelverzeichnis kennt.Stattdessen sollte eine "gute Implementierung" den Anspruch haben, die
path
-Abstraktion nach bestem Wissen und Gewissen auf die nativen OS-Funktionen zu übertragen._wstat64
und die Exception ist also m.E. zwar ein konformes Verhalten (schliesslich wird eine OS/C-Runtime-Funktion korrekt verewendet und meldet einen Fehler), aber eine "gute Implementierung" sollte sich schon mehr Mühe gebenWürde mich nicht wundern, wenn die
libc++
damit klar käme. Da habe ich wenn ich mich recht entsinne relativ viel Code gesehen, der Funktionen der Win32-API direkt aufruft. Funktioniert die bei der MSYS2-Distribution, die du verwendest, @HarteWare?clang++ -stdlib=libc++
... wäre vielleicht mal einen Versuch wert. So aus dem Bauch heraus wirkt mir die Windows-Unterstützung beim LLVM-Projekt generell etwas ernsthafter.Edit: Hab das mal bei mir ausprobiert und bekomme mit GCC nicht einmal eine Exception. Es ist, als würden sämtliche Verzeichnisse mit einem zu langen Pfad überhaupt nicht existieren.
Ich verwende allerdings eine selbst gebaute Toolchain - die dürfte weitgehend dem MSYS2-Build entsprechen, verwendet aber bereits MinGW-w64 10.0. Die Header, die für
_wstat64
und die Win32-API eingebunden werden stammen von diesem Projekt und die machen dort durchaus schonmal Anpassungen:> gcc -dumpversion 12.2.0 > clang++ -dumpversion 16.0.0
... std::cout << "MinGW-w64 " << __MINGW64_VERSION_MAJOR << "." <<__MINGW64_VERSION_MINOR << std::endl; ...
MinGW-w64 10.0
Mit
clang++ -stdlib=libc++
bekomme ich hingegen eine Exception:filesystem error: in recursive_directory_iterator::operator++(): attempting recursion into "D:/Temp/test-fs\very-long-path-subdirectory1\very-long-path-subdirectory2\very-long-path-subdirectory3\very-long-path-subdirectory4\very-long-path-subdirectory5\very-long-path-subdirectory6\very-long-path-subdirectory7\very-long-path-subdirectory8\very-long-path-subdirectory9": No such file or directory
Schon interessant, aber zugegeben, alles nicht zufriedenstellend... eher im Gegenteil, wenn das Verhalten jetzt auch noch scheinbar von der MingGW-w64-Version abhängt und es trotzdem nicht funktioniert wie es soll
-
Dieser Beitrag wurde gelöscht!
-
@Finnegan
Was der Standard vorschreiben sollte und was nicht ist eine Sache.
Was die Implementierung machen sollte mMn. eine andere.Ich finde es halt doof, dass es auf Windows mit standard C++ nicht möglich ist bestimmte Verzeichnisse aufzulisten -- obwohl es mit anderen Programmen sehr wohl möglich ist auf diese Verzeichnisse/Files zuzugreifen. Fälle wo man in das Limit läuft sind auch gar nicht so selten.
Bei anderen Dingen die theoretisch auf Windows möglich sind wird es dann etwas schwieriger. Z.B. kannst du auf Windows normalerweise keine Files erzeugen die "reservierte" Namen wie "CON" oder "COM1" haben. Mit dem
\\?\
Prefix geht es aber. Das Erzeugen von solchen Files über die C++ Standard Library zu erlauben fände ich z.B. nicht so gut.
-
@hustbaer sagte in [Gelöst] std::filesystem_error bei path > MAX_PATH:
@Finnegan
Was der Standard vorschreiben sollte und was nicht ist eine Sache.
Was die Implementierung machen sollte mMn. eine andere.Ich finde es halt doof, dass es auf Windows mit standard C++ nicht möglich ist bestimmte Verzeichnisse aufzulisten -- obwohl es mit anderen Programmen sehr wohl möglich ist auf diese Verzeichnisse/Files zuzugreifen. Fälle wo man in das Limit läuft sind auch gar nicht so selten.
Ja, das geht mir auch schon seit ewig gehörig auf die Nerven - ich hab oft mit tiefen Verzeichnisstrukturen zu tun habe die zur Verarbeitung nochmal ein paar extra Verzeichnisse tief ausgepackt werden. Dazu noch das Locking von Dateien, wo man sich doch oft fragt welcher Prozess denn da noch welche Datei offen hat, dass Löschen nicht wirklich atomar bezüglich Metadaten ist (VMS-Relikt: Dateien werden erstmal nur zum Löschen vorgemerkt und dann meistens nur sehr kurze Zeit später tatsächlich gelöscht - manchmal dauerts aber auch länger), die furchtbar langsame Handhabung von kleinen Dateien und die nicht sonderlich flotte Erzeugung von neuen Prozessen. Ich bin für Dinge, wo das alles besonders stark einschlägt (z.B. die eigene GCC-Toolchain bauen) aus diesen Gründen sogar dazu übergegangen, das nur noch in einem Linux-Container zu machen. Das ist ohne Scheiss 10 mal so schnell bei wesentlich weniger Kopfschmerzen
Ich hab grad das
GetFileAttributesExW
mal mit einem zu langen Verzeichnisnamen getestet. Das schlägt bei mir selbst mitLongPathsEnabled = 1
sowohl unter MinGW-w64 als auch mit Visual Studio fehl. Ich hatte eigentlich gedacht, da bräuchte es kein\\?\
-Voodoo, wegen "These are the file management functions that no longer have MAX_PATH restrictions if you opt-in to long path behavior", aber @HarteWare hatte das ja auch schon angedeutet. Das ist schon übel und erklärt, warum lange Pfade immer noch so viele Probleme machen. Anscheinend muss jedes Programm, das die ordentlich unterstützen will, selbst in dieses Pfadformat konvertieren - mit allen Sonderfällen bezüglich relativen Pfaden - sehe ich das richtig?Wenn das stimmt, dann sehe das Problem vor allem darin, dass MS hier so ein Geraffel als Lösung implementiert hat anstatt das bei
LongPathsEnabled = 1
völlig transparent für sämtliche Dateisystem-Operationen zu machen - inklusive des Lowelevel-I/O der C-Runtime (_open
,_wstat64
, etc.). Immerhin werden die langen Pfade laut Doku für jeden neuen Prozess aktiviert. Wenn man dann ein inkompatibles Programm verwendet, das z.B. blind in einenwchar_t[MAX_PATH]
kopiert, ist man selbst schuld.Und Holla die Waldfee, mein etwas angestaubtes Visual Studio (2022, 17.2.0) wirft beim Testprogramm von @HarteWare ebenfalls:
recursive_directory_iterator::operator++: Das System kann den angegebenen Pfad nicht finden.
... sobald der Iterator beim zu langen Pfad ankommt.
Sieht so aus, als bekommt das nichtmal MS ordentlich hin
Bei anderen Dingen die theoretisch auf Windows möglich sind wird es dann etwas schwieriger. Z.B. kannst du auf Windows normalerweise keine Files erzeugen die "reservierte" Namen wie "CON" oder "COM1" haben. Mit dem
\\?\
Prefix geht es aber. Das Erzeugen von solchen Files über die C++ Standard Library zu erlauben fände ich z.B. nicht so gut.Wenn man wirklich will, dass solche Dinge "einfach funktionieren" dann sollte man das Problem möglichst an der Wurzel anpacken. Mein Problem, das in der C++-Standardbibliothek zu implementieren ist, dass eben nur neu gebaute C++-Programme davon profitieren. Und das erstreckt sich nicht nur über
std::filesystem
- auch Funktionen wiefstream::open
sollten mit diesen Pfaden umgehen können.Die beste Lösung hat m.E. MS verbaut, da böte sich vielleicht am ehesten an, den Support dafür transparent in einer Lowlevel-Abstraktion zu implementieren. Die
libc++
implementiert z.B. sowas in die Richtung - POSIX-Funktionen wiestat
,open
,close
. Da könnte man sowas z.B. einbauen. Noch besser vielleicht, wenn man das in MinGW einbaut. GCC und andere Programme könnten dann auf eine Reihe windows-spezifischer#ifdef
s verzichten und einfach diese Funktionen verwenden - löst natürlich das Problem nicht für Programme, die diese#ifdef
s immer noch drin haben und ist daher auch keine wirklich gute Lösung.Man könnte auch so verwegen sein und das in MinGW direkt in
GetFileAttributesExW
,_wstat64
et al. einbauen - so wie es MS hätte machen sollen. Das hat aber einiges an Potential, ordentlich schief zu gehen und widerspricht wohl auch dem Anspruch von MinGW eine API zur Verfügung zu stellen, die sich exakt wie die von MS verhält. Wäre aber m.E. die einzige Möglichkeit mit der dann alle Programme "einfach so" funktionieren - zumindest die neu mit MinGW kompiliertenP.S.:
@SeppJ sagte in [Gelöst] std::filesystem_error bei path > MAX_PATH:@Tyrdal sagte in [Gelöst] std::filesystem_error bei path > MAX_PATH:
@Swordfish Wie nimmt man den Python, um in C++ Plattformunabhängig mit Dateien zu arbeiten?
system("python script.py")
Hat das mal jemand ausprobiert? Nach dem was ich bisher gesehen habe, würde es mich nicht wundern, wenn auch Python das Problem hat
Edit: Ne, sieht gut aus:
>>> import os >>> os.stat("D:\\Temp\\test-fs\\very-long-path-subdirectory1\\very-long-path-subdirectory2\\very-long-path-subdirectory3\\very-long-path-subdirectory4\\very-long-path-subdirectory5\\very-long-path-subdirectory6\\very-long-path-subdirectory7\\very-long-path-subdirectory8\\very-long-path-subdirectory9\\very-long-path-subdirectory10\\very-long-path-subdirectory11\\") os.stat_result(st_mode=16895, st_ino=2251799813742350, st_dev=1077506507, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1682013939, st_mtime=1682013838, st_ctime=1682013838)
... wär mal interessant zu sehen, wie die das machen.
-
Weitere Beobachtungen mit Datei
D:\Temp\test-fs\very-long-path-subdirectory1\very-long-path-subdirectory2\very-long-path-subdirectory3\very-long-path-subdirectory4\very-long-path-subdirectory5\very-long-path-subdirectory6\very-long-path-subdirectory7\very-long-path-subdirectory8\very-long-path-subdirectory9\very-long-path-subdirectory10\very-long-path-subdirectory11\test.txt
Explorer -> Rechtsklick "test.txt" -> Öffnen:
"Explorer.EXE: Der Verzeichnisname ist ungültig."Explorer -> Rechtsklick "test.txt" -> Edit with Nodepad++: nichts passiert.
Explorer -> Rechtsklick Ordner-Hintergrund von "long-path-subdirectory11" -> Neu: Keine Optionen, um neue Dateien im Ordner zu erstellen (im Gegensatz zu Ordnern mit nicht-überlangem Pfad). Lediglich eine "Ordner"-Option mit Admin-Symbol davor. Nichts passiert, wenn ich das klicke.
Die MSYS2-Bash-Shell scheint das alles nicht zu interessieren und funktioniert wie erwartet:
…ery-long-path-subdirectory8/very-long-path-subdirectory9/very-long-path-subdirectory10/very-long-path-subdirectory11 $ echo TEST > test.txt $ cat test.txt TEST
Die machen in MSYS2 auch intern viel Pfadübersetzungs-Zeug, z.B. Dinge wie
/c/verzeichnis
in Programm-Argumenten transparent nachC:\verzeichnis
zu übersetzen, was überraschend gut funktioniert. Es wundert mich also eher weniger, dass MSYS2 damit klar kommt.wsl.exe
scheint auch so seine Probleme zu haben:PS > cd \\?\D:\Temp\test-fs\very-long-path-subdirectory1\very-long-path-subdirectory2\very-long-path-subdirectory3\very-long-path-subdirectory4\very-long-path-subdirectory5\very-long-path-subdirectory6\very-long-path-subdirectory7\very-long-path-subdirectory8\very-long-path-subdirectory9\very-long-path-subdirectory10\very-long-path-subdirectory11 PS > wsl Fehler beim Ausführen des Programms "wsl.exe": Der Verzeichnisname ist ungültig
Innerhalb des WSL-Linux wie erwartet keine Probleme:
> cd /mnt/d/Temp/test-fs/very-long-path-subdirectory1/very-long-path-subdirectory2/very-long-path-subdirectory3/very-long-path-subdirectory4/very-long-path-subdirectory5/very-long-path-subdirectory6/very-long-path-subdirectory7/very-long-path-subdirectory8/very-long-path-subdirectory9/very-long-path-subdirectory10/very-long-path-subdirectory11/ > cat test.txt TEST
... was ein Chaos
-
@Finnegan sagte in [Gelöst] std::filesystem_error bei path > MAX_PATH:
Anscheinend muss jedes Programm, das die ordentlich unterstützen will, selbst in dieses Pfadformat konvertieren - mit allen Sonderfällen bezüglich relativen Pfaden - sehe ich das richtig?
Relative Pfade kann man mit GetFullPathNameW erschlagen. Das scheint auch mit langen Pfaden zu funktionieren ohne dass man das blöde
\\?\
vorn anhängt. Das Ersetzen von/
durch\
übernimmt auchGetFullPathNameW
.Mit "verbotenen" Namen ala CON, COM1 etc. kommt bei
GetFullPathNameW
aber u.U. Blödsinn raus - bzw. halt nicht unbedingt das was man möchte. Wenn's mittem im Pfad vorkommt, dann bleiben die verbotenen Namen erhalten. Sobald allerdings das letzte Pfad-Segment ein verbotener Name ist (oder auch ein verbotener Name gefolgt von einer Extension), dann bekommt man als Ergebnis den "Device-Path" der dem verbotenen Namen entspricht. Also z.B. ausC:\Foo\Bar\CON.txt
wird\\.\CON
.Den Fall sollte man vermutlich also noch selbst abdecken. Wie man den dann behandelt kann man sich aussuchen. Entweder man bastelt einen Workaround für den Fall, z.B. indem man den verbotenen Namen in einen nicht verbotenen ändert, dann
GetFullPathNameW
aufruft und dann den letzten Teil des Ergebnisses wieder auf den verbotenen Namen zurückändert. Oder indem man solche Pfade einfach verbietet - z.B. indem man prüft ob das Ergebnis mit\\.\
anfängt.Wenn das stimmt, dann sehe das Problem vor allem darin, dass MS hier so ein Geraffel als Lösung implementiert hat anstatt das bei
LongPathsEnabled = 1
völlig transparent für sämtliche Dateisystem-Operationen zu machen - inklusive des Lowelevel-I/O der C-Runtime (_open
,_wstat64
, etc.). Immerhin werden die langen Pfade laut Doku für jeden neuen Prozess aktiviert. Wenn man dann ein inkompatibles Programm verwendet, das z.B. blind in einenwchar_t[MAX_PATH]
kopiert, ist man selbst schuld.Tja. Pfuh. Wobei es mir wenig bringen würde wenn das über die Registry super funktionieren würde. Unsere Programme müssen auf allen möglichen Systemen laufen, und wir können nicht von unseren Benutzern verlangen dass sie Einstellungen in der Registry ändern. (Und automatisch ändern dürfen wir sie schon gar nicht.)
Und Holla die Waldfee, mein etwas angestaubtes Visual Studio (2022, 17.2.0) wirft beim Testprogramm von @HarteWare ebenfalls:
recursive_directory_iterator::operator++: Das System kann den angegebenen Pfad nicht finden.
... sobald der Iterator beim zu langen Pfad ankommt.
Sieht so aus, als bekommt das nichtmal MS ordentlich hin
Ja, richtig. Ich dachte das wäre aus der Verlauf des Threads mittlerweile klar geworden
...
Wie gesagt: ich fände es gut wenn zumindest Support für lange Pfade transparent in der MSVC Standard Library (bzw. jeder Standard Library für Windows) verbaut wäre. Und damit meine ich natürlich nicht nur
std::filesystem
sondern auch den "libc" Teil (open
,fopen
,_wfopen
etc.).
-
@hustbaer sagte in [Gelöst] std::filesystem_error bei path > MAX_PATH:
Tja. Pfuh. Wobei es mir wenig bringen würde wenn das über die Registry super funktionieren würde. Unsere Programme müssen auf allen möglichen Systemen laufen, und wir können nicht von unseren Benutzern verlangen dass sie Einstellungen in der Registry ändern. (Und automatisch ändern dürfen wir sie schon gar nicht.)
Aus MS-Doku:
The registry key
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled
(Type:REG_DWORD
) must exist and be set to 1. The key's value will be cached by the system (per process) after the first call to an affected Win32 file or directory function (see below for the list of functions).Das klingt so, als hätte man auch eine Funktion zur Verfügung stellen können, die beim Programmstart aufgerufen wird und das Flag für den Prozess setzt. Müsste man wahrscheinlich in den Startup-Code einbauen (wo vermutlich das erste mal eine betroffene Dateisystem-Funktion aufgerufen wird) und das dann über eine Compiler-Option aktivieren - ähnlich wie z.B. das GCC-Flag
-mcrtdll
für die Auswahl der MSVCRT/UCRT Runtime oder die Flags, mit denen man auswählt, ob Konsolen- oder GUI-Programm (/SUBSYSTEM:console
/-mconsole
). Das wäre jedenfalls sinnvoller ausrollbar als der Registry-Schlüssel. Dann braucht man auch noch weniger auf irgendwelche Kompatibilitätsprobleme zu achten, wenn die Entwickler des Programms das schon explizit angeben.Vor allem muss die Voraussetzung fallen, dass es nur mit
\\?\
-Pfaden funktioniert. Das erachte ich als größte Hürde. Besonders für auf Windows portierte Programme und Bibliotheken. Ist ja schön und gut, wenn man das im eigenen Code richtig macht - nur was ist mit den 20 gelinkten Libs, die ebenfalls mit Pfaden hantieren?Und Holla die Waldfee, mein etwas angestaubtes Visual Studio (2022, 17.2.0) wirft beim Testprogramm von @HarteWare ebenfalls:
recursive_directory_iterator::operator++: Das System kann den angegebenen Pfad nicht finden.
... sobald der Iterator beim zu langen Pfad ankommt.
Sieht so aus, als bekommt das nichtmal MS ordentlich hin
Ja, richtig. Ich dachte das wäre aus der Verlauf des Threads mittlerweile klar geworden
Ich muss zu meiner Schade gestehen, dass ich dazu neige, längere Threads eher querzulesen und mir dabei gerne etwas entgeht. Das ist nicht das erste mal, dass mir erst später etwas auffällt, das eigentlich schon geklärt war ... immer etwas peinlich
-
@Finnegan Es wäre natürlich für viele Anwendungen super wenn man das irgendwie im Programm selbst aktivieren könnte. Also z.B. per API-call, Linker-Flag oder Manifest.
Uns würde das allerdings nur wenig bringen, da ein grosser Teil unseres Codes im Kontext von fremden Prozessen läuft. Und in denen dürfen wir keinen globalen State des Prozesses ändern, selbst wenn wir es können.
-
@hustbaer sagte in [Gelöst] std::filesystem_error bei path > MAX_PATH:
Uns würde das allerdings nur wenig bringen, da ein grosser Teil unseres Codes im Kontext von fremden Prozessen läuft. Und in denen dürfen wir keinen globalen State des Prozesses ändern, selbst wenn wir es können.
Schon klar dass der Code, der den Prozess aufmacht ihn auch exklusiv konfiguriert. Da kann man dann wohl nichts machen... ausser die Dateisystemzugriffe in einem weiteren Prozess zu machen, den ihr selbst startet und mit dem euer Code dann kommuniziert
-
Da kann man dann wohl nichts machen... ausser die Dateisystemzugriffe in einem weiteren Prozess zu machen, den ihr selbst startet und mit dem euer Code dann kommuniziert
Nö
Was wir machen werden damit wir endlich keine Probleme mehr mit langen Pfaden haben ist die Pfade selbst zu "konvertieren", per
GetFullPathNameW
+ Check auf verbotene Namen + voranstellen von\\?\
.
-
@hustbaer sagte in [Gelöst] std::filesystem_error bei path > MAX_PATH:
Was wir machen werden damit wir endlich keine Probleme mehr mit langen Pfaden haben ist die Pfade selbst zu "konvertieren", per
GetFullPathNameW
+ Check auf verbotene Namen + voranstellen von\\?\
.Darf ich mal ne ganz doofe Frage stellen, die mir wieder peinlich werden könnte? ... was macht eigentlich
LongPathsEnabled
, wenn es auch so mit\\?\
-Pfaden funktionieren soll?Mein Eindruck beim Testen war, dass
\\?\
auch dann gebraucht wird, wenn man das aktiv hat. Oder hat mir da vielleicht irgendwas dazwischen gefunkt?GetFileAttributesExW
hat bei mir auch mitLongPathsEnabled = 1
einen Fehler zurückgegeben, wenn das\\?\
fehlte.
-
@Finnegan Ich habe das nicht probiert, sondern gerade nur in der Doku gefunden. Angeblich muss man Long Path Awareness noch im Application Manifest setzen:
<ws2:longPathAware>true</ws2:longPathAware>
Edit: Das kann aber ja eigentlich nicht die Lösung für PS sein oO
-
@Schlangenmensch sagte in [Gelöst] std::filesystem_error bei path > MAX_PATH:
@Finnegan Ich habe das nicht probiert, sondern gerade nur in der Doku gefunden. Angeblich muss man Long Path Awareness noch im Application Manifest setzen:
<ws2:longPathAware>true</ws2:longPathAware>
Hah! Das ist ja wie bei den Flugzeugbauern: Mehrfach redundante Sicherheitssysteme stellen sicher, dass nicht am Ende noch jemand mit dem OS produktiv arbeiten kann
Mal ehrlich, das mit dem Manifest hätte echt gereicht - aber schön, dass es scheinbar auch ohne das Registry-Flag klappt - so bleibt immerhin eine gut kompatible Lösung.
Ich bin ja bei Dateisystem-Zugriffen eher ein Fan davon, mit Handles zu arbeiten statt mit Pfaden und String-Operationen zu hantieren. Unter Linux geht das mit
open()
undopenat()
. Hat den Vorteil, dass die Operationen atomar sind, man Dateisystem-Races vermeidet und ein Handle offen hält, wodurch man den Zugriff auf das Verzeichnis nicht verliert wenn es gelöscht oder verschoben wird. Einem damit implementierten Directory Iterator könnte man im laufenden Betrieb das Wurzelverzeichnis verschieben und der würde immer noch korrekt durchlaufen. Ist ein praktisches Verhalten für Tools, die lange Zeit in einem Verzeichnisbaum arbeiten und man sich währenddessen überlegt, den umzubenennen oder an eine sinnvollere Stelle zu packen.