¿Cómo recorre cada archivo / directorio de forma recursiva en C ++ estándar?
c++
filesystems
robottobor
fuente
fuente
Respuestas:
En C ++ estándar, técnicamente no hay forma de hacer esto ya que C ++ estándar no tiene un concepto de directorios. Si desea expandir su red un poco, le recomendamos que use Boost.FileSystem . Esto ha sido aceptado para su inclusión en TR2, por lo que le brinda la mejor oportunidad de mantener su implementación lo más cercana posible al estándar.
Un ejemplo, tomado directamente del sitio web:
fuente
Desde C ++ 17 en adelante, el
<filesystem>
encabezado y el rangofor
, simplemente puede hacer esto:A partir de C ++ 17,
std::filesystem
es parte de la biblioteca estándar y se puede encontrar en el<filesystem>
encabezado (ya no es "experimental").fuente
using
, usenamespace
en su lugar.Si usa la API de Win32, puede usar las funciones FindFirstFile y FindNextFile .
http://msdn.microsoft.com/en-us/library/aa365200(VS.85).aspx
Para el recorrido recursivo de directorios, debe inspeccionar cada WIN32_FIND_DATA.dwFileAttributes para verificar si el bit FILE_ATTRIBUTE_DIRECTORY está establecido. Si el bit está establecido, puede llamar de forma recursiva a la función con ese directorio. Alternativamente, puede usar una pila para proporcionar el mismo efecto de una llamada recursiva pero evitando el desbordamiento de la pila para árboles de ruta muy largos.
fuente
Puede hacerlo aún más simple con el nuevo rango C ++ 11 basado
for
y Boost :fuente
Una solución rápida es usar la biblioteca Dirent.h de C.
Fragmento de código de trabajo de Wikipedia:
fuente
Además del sistema de archivos boost :: mencionado anteriormente, es posible que desee examinar wxWidgets :: wxDir y Qt :: QDir .
Tanto wxWidgets como Qt son frameworks C ++ de código abierto y multiplataforma.
wxDir
proporciona una forma flexible de recorrer archivos de forma recursiva utilizandoTraverse()
o unaGetAllFiles()
función más simple . También puede implementar el recorrido conGetFirst()
yGetNext()
funciones (supongo que Traverse () y GetAllFiles () son contenedores que eventualmente usan las funciones GetFirst () y GetNext ()).QDir
proporciona acceso a las estructuras de directorios y su contenido. Hay varias formas de recorrer directorios con QDir. Puede iterar sobre el contenido del directorio (incluidos los subdirectorios) con QDirIterator que se instancia con el indicador QDirIterator :: Subdirectories. Otra forma es usar la función GetEntryList () de QDir e implementar un recorrido recursivo.Aquí hay un código de muestra (tomado de aquí # Ejemplo 8-5) que muestra cómo iterar sobre todos los subdirectorios.
fuente
Boost :: filesystem proporciona recursive_directory_iterator, que es bastante conveniente para esta tarea:
fuente
Puede usar
ftw(3)
onftw(3)
recorrer una jerarquía de sistemas de archivos en C o C ++ en sistemas POSIX .fuente
nftw()
uso.Tu no El estándar C ++ no tiene concepto de directorios. Depende de la implementación convertir una cadena en un identificador de archivo. El contenido de esa cadena y lo que se asigna depende del sistema operativo. Tenga en cuenta que C ++ se puede usar para escribir ese sistema operativo, por lo que se usa en un nivel en el que aún no está definido preguntar cómo iterar a través de un directorio (porque está escribiendo el código de administración del directorio).
Consulte la documentación de la API de su sistema operativo para saber cómo hacer esto. Si necesita ser portátil, tendrá que tener un montón de #ifdef s para varios sistemas operativos.
fuente
Probablemente sería mejor con boost o con el sistema de archivos experimental de c ++ 14. SI está analizando un directorio interno (es decir, utilizado por su programa para almacenar datos después de que se cerró el programa), entonces cree un archivo de índice que tenga un índice del contenido del archivo. Por cierto, probablemente necesitará usar boost en el futuro, así que si no lo tiene instalado, ¡instálelo! En segundo lugar, podría usar una compilación condicional, por ejemplo:
El código para cada caso se toma de https://stackoverflow.com/a/67336/7077165
fuente
Necesita llamar a funciones específicas del sistema operativo para el recorrido del sistema de archivos, como
open()
yreaddir()
. El estándar C no especifica ninguna función relacionada con el sistema de archivos.fuente
Estamos en 2019. Tenemos la biblioteca estándar del sistema de archivos en formato
C++
. losFilesystem library
proporciona facilidades para la realización de operaciones en sistemas de archivos y sus componentes, tales como caminos, archivos regulares y directorios.Hay una nota importante en este enlace si está considerando problemas de portabilidad. Dice:
La biblioteca del sistema de archivos se desarrolló originalmente como
boost.filesystem
, se publicó como la especificación técnica ISO / IEC TS 18822: 2015, y finalmente se fusionó con ISO C ++ a partir de C ++ 17. La implementación de boost está disponible actualmente en más compiladores y plataformas que la biblioteca C ++ 17.@ adi-shavit ha respondido a esta pregunta cuando era parte de std :: experimental y ha actualizado esta respuesta en 2017. Quiero dar más detalles sobre la biblioteca y mostrar un ejemplo más detallado.
std :: filesystem :: recursive_directory_iterator es un elemento
LegacyInputIterator
que itera sobre los elementos directory_entry de un directorio y, de forma recursiva, sobre las entradas de todos los subdirectorios. El orden de iteración no está especificado, excepto que cada entrada de directorio se visita solo una vez.Si no desea iterar de forma recursiva sobre las entradas de los subdirectorios, debe utilizar directory_iterator .
Ambos iteradores devuelven un objeto de directory_entry .
directory_entry
tiene varias funciones miembro útil comois_regular_file
,is_directory
,is_socket
,is_symlink
etc. Laspath()
funciones miembro devuelve un objeto de std :: sistema de archivos :: trayectoria y que puede ser utilizado para obtenerfile extension
,filename
,root name
.Considere el siguiente ejemplo. Lo he estado usando
Ubuntu
y compilado en la terminal usandog ++ ejemplo.cpp --std = c ++ 17 -lstdc ++ fs -Wall
fuente
Tu no C ++ estándar no se expone al concepto de directorio. Específicamente, no da ninguna forma de listar todos los archivos en un directorio.
Un truco horrible sería usar llamadas al sistema () y analizar los resultados. La solución más razonable sería utilizar algún tipo de biblioteca multiplataforma como Qt o incluso POSIX .
fuente
Puede utilizar
std::filesystem::recursive_directory_iterator
. Pero tenga cuidado, esto incluye enlaces simbólicos (suaves). Si quieres evitarlos puedes usaris_symlink
. Uso de ejemplo:fuente
Si está en Windows, puede usar FindFirstFile junto con FindNextFile API. Puede utilizar FindFileData.dwFileAttributes para comprobar si una ruta determinada es un archivo o un directorio. Si es un directorio, puede repetir el algoritmo de forma recursiva.
Aquí, he reunido un código que enumera todos los archivos en una máquina con Windows.
http://dreams-soft.com/projects/traverse-directory
fuente
La caminata por el árbol de archivos
ftw
es una forma recursiva de crear un muro en todo el árbol de directorios en la ruta. Más detalles están aquí .NOTA: También puede usar
fts
que puede omitir archivos ocultos como.
o..
o.bashrc
la salida se parece a lo siguiente:
Digamos que si desea hacer coincidir un nombre de archivo (ejemplo: buscar todos los
*.jpg, *.jpeg, *.png
archivos) para necesidades específicas, usefnmatch
.fuente