Comment parcourez-vous chaque fichier / répertoire de manière récursive en C ++ standard?
c++
filesystems
Robottobor
la source
la source
Réponses:
En C ++ standard, techniquement, il n'y a aucun moyen de le faire puisque le C ++ standard n'a aucune conception des répertoires. Si vous souhaitez élargir un peu votre réseau, vous voudrez peut-être envisager d'utiliser Boost.FileSystem . Cela a été accepté pour inclusion dans TR2, ce qui vous donne les meilleures chances de garder votre implémentation aussi proche que possible de la norme.
Un exemple, tiré directement du site Web:
la source
À partir de C ++ 17, l'en-
<filesystem>
tête et la plage-for
, vous pouvez simplement faire ceci:Depuis C ++ 17,
std::filesystem
fait partie de la bibliothèque standard et peut être trouvé dans l'en-<filesystem>
tête (plus "expérimental").la source
using
utiliser, utiliseznamespace
plutôt.Si vous utilisez l'API Win32, vous pouvez utiliser les fonctions FindFirstFile et FindNextFile .
http://msdn.microsoft.com/en-us/library/aa365200(VS.85).aspx
Pour le parcours récursif de répertoires, vous devez inspecter chaque WIN32_FIND_DATA.dwFileAttributes pour vérifier si le bit FILE_ATTRIBUTE_DIRECTORY est défini. Si le bit est défini, vous pouvez appeler la fonction de manière récursive avec ce répertoire. Vous pouvez également utiliser une pile pour fournir le même effet qu'un appel récursif mais en évitant le débordement de pile pour les arbres de chemins très longs.
la source
Vous pouvez le rendre encore plus simple avec la nouvelle gamme C ++ 11 basée
for
et Boost :la source
Une solution rapide consiste à utiliser la bibliothèque Dirent.h de C.
Fragment de code de travail de Wikipedia:
la source
En plus du système de fichiers boost :: mentionné ci-dessus, vous voudrez peut-être examiner wxWidgets :: wxDir et Qt :: QDir .
WxWidgets et Qt sont des frameworks C ++ multiplateformes open source.
wxDir
fournit un moyen flexible de parcourir les fichiers de manière récursive en utilisantTraverse()
ou uneGetAllFiles()
fonction plus simple . De plus, vous pouvez implémenter le parcours avec les fonctionsGetFirst()
etGetNext()
(je suppose que Traverse () et GetAllFiles () sont des wrappers qui utilisent finalement les fonctions GetFirst () et GetNext ()).QDir
donne accès aux structures de répertoires et à leur contenu. Il existe plusieurs façons de parcourir les répertoires avec QDir. Vous pouvez parcourir le contenu du répertoire (y compris les sous-répertoires) avec QDirIterator qui a été instancié avec l'indicateur QDirIterator :: Subdirectories. Une autre façon consiste à utiliser la fonction GetEntryList () de QDir et à implémenter un parcours récursif.Voici un exemple de code (tiré d' ici # Exemple 8-5) qui montre comment parcourir tous les sous-répertoires.
la source
Boost :: filesystem fournit recursive_directory_iterator, ce qui est assez pratique pour cette tâche:
la source
Vous pouvez utiliser
ftw(3)
ounftw(3)
pour parcourir une hiérarchie de système de fichiers en C ou C ++ sur les systèmes POSIX .la source
nftw()
utilisation.Vous ne le faites pas. Le standard C ++ n'a pas de concept de répertoires. C'est à l'implémentation de transformer une chaîne en descripteur de fichier. Le contenu de cette chaîne et son mappage dépendent du système d'exploitation. Gardez à l'esprit que C ++ peut être utilisé pour écrire ce système d'exploitation, il est donc utilisé à un niveau où le fait de demander comment parcourir un répertoire n'est pas encore défini (car vous écrivez le code de gestion de répertoire).
Consultez la documentation de votre API OS pour savoir comment procéder. Si vous avez besoin d'être portable, vous devrez avoir un tas de #ifdef pour différents OS.
la source
Vous seriez probablement mieux avec le système de fichiers expérimental de boost ou de c ++ 14. SI vous analysez un répertoire interne (c'est-à-dire utilisé par votre programme pour stocker des données après la fermeture du programme), créez un fichier d'index contenant un index du contenu du fichier. Au fait, vous devrez probablement utiliser boost à l'avenir, donc si vous ne l'avez pas installé, installez-le! Deuxièmement, vous pouvez utiliser une compilation conditionnelle, par exemple:
Le code pour chaque cas est tiré de https://stackoverflow.com/a/67336/7077165
la source
Vous devez appeler des fonctions spécifiques au système d'exploitation pour la traversée du système de fichiers, comme
open()
etreaddir()
. La norme C ne spécifie aucune fonction liée au système de fichiers.la source
Nous sommes en 2019. Nous avons une bibliothèque standard de système de fichiers dans
C++
. leFilesystem library
fournit des fonctionnalités pour effectuer des opérations sur les systèmes de fichiers et leurs composants, tels que les chemins, les fichiers normaux et les répertoires.Il y a une note importante sur ce lien si vous envisagez des problèmes de portabilité. Ça dit:
La bibliothèque de système de fichiers a été initialement développée en tant que
boost.filesystem
, a été publiée en tant que spécification technique ISO / IEC TS 18822: 2015, et finalement fusionnée avec ISO C ++ à partir de C ++ 17. L'implémentation boost est actuellement disponible sur plus de compilateurs et de plates-formes que la bibliothèque C ++ 17.@ adi-shavit a répondu à cette question lorsqu'elle faisait partie de std :: experimental et il a mis à jour cette réponse en 2017. Je veux donner plus de détails sur la bibliothèque et montrer un exemple plus détaillé.
std :: filesystem :: recursive_directory_iterator est un
LegacyInputIterator
qui itère sur les éléments directory_entry d'un répertoire et, de manière récursive, sur les entrées de tous les sous-répertoires. L'ordre d'itération n'est pas spécifié, sauf que chaque entrée de répertoire n'est visitée qu'une seule fois.Si vous ne voulez pas itérer récursivement sur les entrées des sous-répertoires, alors directory_iterator doit être utilisé.
Les deux itérateurs retournent un objet de type directory_entry .
directory_entry
a diverses fonctions membres utiles commeis_regular_file
,is_directory
,is_socket
,is_symlink
etc. Lapath()
fonction membre retourne un objet de std :: :: système de fichiers chemin et il peut être utilisé pour obtenirfile extension
,filename
,root name
.Prenons l'exemple ci-dessous. Je l'ai utilisé
Ubuntu
et compilé sur le terminal en utilisantg ++ example.cpp --std = c ++ 17 -lstdc ++ fs -Wall
la source
Vous ne le faites pas. Le C ++ standard n'expose pas le concept de répertoire. Plus précisément, cela ne donne aucun moyen de lister tous les fichiers dans un répertoire.
Un horrible hack serait d'utiliser des appels system () et d'analyser les résultats. La solution la plus raisonnable serait d'utiliser une sorte de bibliothèque multiplateforme telle que Qt ou même POSIX .
la source
Vous pouvez utiliser
std::filesystem::recursive_directory_iterator
. Mais attention, cela inclut les liens symboliques (logiciels). Si vous voulez les éviter, vous pouvez utiliseris_symlink
. Exemple d'utilisation:la source
Si vous êtes sous Windows, vous pouvez utiliser FindFirstFile avec l'API FindNextFile. Vous pouvez utiliser FindFileData.dwFileAttributes pour vérifier si un chemin donné est un fichier ou un répertoire. S'il s'agit d'un répertoire, vous pouvez répéter l'algorithme de manière récursive.
Ici, j'ai rassemblé un code qui répertorie tous les fichiers sur une machine Windows.
http://dreams-soft.com/projects/traverse-directory
la source
La marche dans l'arborescence des fichiers
ftw
est une manière récursive de murer toute l'arborescence de répertoires dans le chemin. Plus de détails ici .REMARQUE: vous pouvez également utiliser
fts
qui peut ignorer les fichiers cachés comme.
ou..
ou.bashrc
la sortie ressemble à ceci:
Disons que si vous voulez faire correspondre un nom de fichier (exemple: rechercher tous les
*.jpg, *.jpeg, *.png
fichiers.) Pour un besoin spécifique, utilisezfnmatch
.la source