Wie iteriert man in Standard-C ++ rekursiv durch jede Datei / jedes Verzeichnis?
c++
filesystems
Robottobor
quelle
quelle
Antworten:
In Standard-C ++ gibt es technisch keine Möglichkeit, dies zu tun, da Standard-C ++ keine Konzeption von Verzeichnissen hat. Wenn Sie Ihr Netz ein wenig erweitern möchten, sollten Sie sich Boost.FileSystem ansehen . Dies wurde für die Aufnahme in TR2 akzeptiert, sodass Sie die beste Chance haben, Ihre Implementierung so nah wie möglich am Standard zu halten.
Ein Beispiel direkt von der Website:
quelle
Ab C ++ 17, dem
<filesystem>
Header und dem Bereichfor
können Sie dies einfach tun:Ab C ++ 17
std::filesystem
ist Teil der Standardbibliothek und befindet sich im<filesystem>
Header (nicht mehr "experimentell").quelle
using
, verwenden Sienamespace
stattdessen.Wenn Sie die Win32-API verwenden, können Sie die Funktionen FindFirstFile und FindNextFile verwenden.
http://msdn.microsoft.com/en-us/library/aa365200(VS.85).aspx
Für das rekursive Durchlaufen von Verzeichnissen müssen Sie jedes WIN32_FIND_DATA.dwFileAttributes überprüfen, um zu überprüfen, ob das Bit FILE_ATTRIBUTE_DIRECTORY gesetzt ist. Wenn das Bit gesetzt ist, können Sie die Funktion mit diesem Verzeichnis rekursiv aufrufen. Alternativ können Sie einen Stapel verwenden, um den gleichen Effekt eines rekursiven Aufrufs zu erzielen, aber einen Stapelüberlauf für sehr lange Pfadbäume zu vermeiden.
quelle
Mit der neuen C ++ 11- Reihe
for
und Boost können Sie es noch einfacher machen :quelle
Eine schnelle Lösung ist die Verwendung der Dirent.h- Bibliothek von C.
Arbeitscodefragment aus Wikipedia:
quelle
Zusätzlich zu dem oben erwähnten Boost :: -Dateisystem möchten Sie möglicherweise wxWidgets :: wxDir und Qt :: QDir untersuchen .
Sowohl wxWidgets als auch Qt sind plattformübergreifende Open Source-C ++ - Frameworks.
wxDir
bietet eine flexible Möglichkeit, Dateien rekursiv zu durchlaufen,Traverse()
oder eine einfachereGetAllFiles()
Funktion. Sie können auch das Traversal mitGetFirst()
undGetNext()
Funktionen implementieren (ich gehe davon aus, dass Traverse () und GetAllFiles () Wrapper sind, die schließlich die Funktionen GetFirst () und GetNext () verwenden).QDir
bietet Zugriff auf Verzeichnisstrukturen und deren Inhalte. Es gibt verschiedene Möglichkeiten, Verzeichnisse mit QDir zu durchlaufen. Sie können den Verzeichnisinhalt (einschließlich der Unterverzeichnisse) mit QDirIterator durchlaufen, der mit dem Flag QDirIterator :: Subdirectories instanziiert wurde. Eine andere Möglichkeit besteht darin, die GetEntryList () -Funktion von QDir zu verwenden und eine rekursive Durchquerung zu implementieren.Hier ist Beispielcode (aus hier # Beispiel 8-5) , die zeigt , wie alle Unterverzeichnisse iterieren.
quelle
Boost :: filesystem bietet recursive_directory_iterator, was für diese Aufgabe sehr praktisch ist:
quelle
Sie können eine Dateisystemhierarchie in C oder C ++ auf POSIX- Systemen verwenden
ftw(3)
odernftw(3)
durchlaufen .quelle
nftw()
Verwendung.Sie sind wahrscheinlich am besten mit Boost oder dem experimentellen Dateisystem von c ++ 14 vertraut. Wenn Sie ein internes Verzeichnis analysieren (dh für Ihr Programm zum Speichern von Daten nach dem Schließen des Programms verwendet werden), erstellen Sie eine Indexdatei mit einem Index des Dateiinhalts. Übrigens müssten Sie wahrscheinlich in Zukunft Boost verwenden. Wenn Sie es also nicht installiert haben, installieren Sie es! Zweitens könnten Sie eine bedingte Kompilierung verwenden, z.
Der Code für jeden Fall stammt von https://stackoverflow.com/a/67336/7077165
quelle
Das tust du nicht. Der C ++ - Standard hat kein Konzept für Verzeichnisse. Es liegt an der Implementierung, eine Zeichenfolge in ein Dateihandle umzuwandeln. Der Inhalt dieser Zeichenfolge und die Zuordnung ist vom Betriebssystem abhängig. Beachten Sie, dass C ++ zum Schreiben dieses Betriebssystems verwendet werden kann, sodass es auf einer Ebene verwendet wird, auf der die Frage, wie ein Verzeichnis durchlaufen werden soll, noch nicht definiert ist (da Sie den Verzeichnisverwaltungscode schreiben).
Informationen dazu finden Sie in der Dokumentation zur Betriebssystem-API. Wenn Sie portabel sein müssen, müssen Sie eine Reihe von #ifdefs für verschiedene Betriebssysteme haben.
quelle
Sie müssen betriebssystemspezifische Funktionen für das Durchlaufen des Dateisystems aufrufen, z. B.
open()
undreaddir()
. Der C-Standard spezifiziert keine dateisystembezogenen Funktionen.quelle
Wir sind im Jahr 2019. Wir haben Dateisystem Standardbibliothek in
C++
. DasFilesystem library
bietet Funktionen zum Ausführen von Vorgängen auf Dateisystemen und deren Komponenten, z. B. Pfaden, regulären Dateien und Verzeichnissen.Dieser Link enthält einen wichtigen Hinweis , wenn Sie Probleme mit der Portabilität in Betracht ziehen. Es sagt:
Die Dateisystembibliothek wurde ursprünglich als entwickelt
boost.filesystem
, als technische Spezifikation ISO / IEC TS 18822: 2015 veröffentlicht und schließlich ab C ++ 17 mit ISO C ++ zusammengeführt. Die Boost-Implementierung ist derzeit auf mehr Compilern und Plattformen als in der C ++ 17-Bibliothek verfügbar.@ adi-shavit hat diese Frage beantwortet, als sie Teil von std :: experimentell war, und er hat diese Antwort 2017 aktualisiert. Ich möchte mehr Details über die Bibliothek geben und ein detaillierteres Beispiel zeigen.
std :: filesystem :: recursive_directory_iterator ist ein
LegacyInputIterator
Befehl, der über die directory_entry-Elemente eines Verzeichnisses und rekursiv über die Einträge aller Unterverzeichnisse iteriert. Die Iterationsreihenfolge ist nicht angegeben, außer dass jeder Verzeichniseintrag nur einmal besucht wird.Wenn Sie die Einträge von Unterverzeichnissen nicht rekursiv durchlaufen möchten, sollte directory_iterator verwendet werden.
Beide Iteratoren geben ein Objekt von directory_entry zurück .
directory_entry
hat verschiedene nützliche Member - Funktionen wieis_regular_file
,is_directory
,is_socket
,is_symlink
etc. Diepath()
Member - Funktion gibt ein Objekt von std :: filesystem :: path und es kann zu bekommen verwendet werdenfile extension
,filename
,root name
.Betrachten Sie das folgende Beispiel. Ich habe es verwendet
Ubuntu
und über das Terminal mit kompiliertg ++ example.cpp --std = c ++ 17 -lstdc ++ fs -Wall
quelle
Das tust du nicht. Standard C ++ ist nicht dem Konzept eines Verzeichnisses ausgesetzt. Insbesondere gibt es keine Möglichkeit, alle Dateien in einem Verzeichnis aufzulisten.
Ein schrecklicher Hack wäre, system () -Aufrufe zu verwenden und die Ergebnisse zu analysieren. Die vernünftigste Lösung wäre die Verwendung einer plattformübergreifenden Bibliothek wie Qt oder sogar POSIX .
quelle
Sie können verwenden
std::filesystem::recursive_directory_iterator
. Beachten Sie jedoch, dass dies auch symbolische (weiche) Links umfasst. Wenn Sie sie vermeiden möchten, können Sie verwendenis_symlink
. Anwendungsbeispiel:quelle
Wenn Sie unter Windows arbeiten, können Sie FindFirstFile zusammen mit der FindNextFile-API verwenden. Mit FindFileData.dwFileAttributes können Sie überprüfen, ob ein bestimmter Pfad eine Datei oder ein Verzeichnis ist. Wenn es sich um ein Verzeichnis handelt, können Sie den Algorithmus rekursiv wiederholen.
Hier habe ich einen Code zusammengestellt, der alle Dateien auf einem Windows-Computer auflistet.
http://dreams-soft.com/projects/traverse-directory
quelle
Der Dateibaumspaziergang
ftw
ist eine rekursive Methode, um den gesamten Verzeichnisbaum im Pfad zu umwandeln. Weitere Details finden Sie hier .HINWEIS: Sie können auch
fts
versteckte Dateien wie.
oder..
oder überspringen.bashrc
Die Ausgabe sieht folgendermaßen aus:
Angenommen, Sie möchten einen Dateinamen (Beispiel: Suche nach allen
*.jpg, *.jpeg, *.png
Dateien) für bestimmte Anforderungen verwendenfnmatch
.quelle