2011-09-03 22 views
6

Por favor, consulte Edición de asesoramiento adoptadas hasta el momento ...Liste de manera eficiente todos los subdirectorios en un directorio

que estoy tratando de enumerar todos los directorios (carpetas) en un directorio determinado, utilizando WinAPI & C++.

Ahora mismo mi algoritmo es lenta & ineficaz:
- Uso FindFirstFileEx() para abrir la carpeta Estoy buscando
- Me continuación, busque en todos los archivos en el directorio (utilizando FindNextFile()); si es un archivo de directorio, entonces almaceno su ruta absoluta en un vector, si es solo un archivo, no hago nada.

Esto parece extremadamente ineficiente porque estoy mirando cada archivo en el directorio.

  • ¿Hay una función API de Windows que puedo usar que me diga todos los subdirectorios en un directorio dado?
  • ¿Conoces un algoritmo que podría utilizar para ubicar de manera eficiente las carpetas de identificación de & en un directorio (carpeta)?

EDIT: Así que después de tomar el consejo He buscado utilizando FindExSearchLimitToDirectories pero para mí todavía imprime todos los archivos (.txt, etc.) & no sólo las carpetas. ¿Estoy haciendo algo mal?

WIN32_FIND_DATA dirData; 
HANDLE dir = FindFirstFileEx("c:/users/soribo/desktop\\*", FindExInfoStandard, &dirData, 
           FindExSearchLimitToDirectories, NULL, 0); 

while (FindNextFile(dir, &dirData) != 0) 
{ 
    printf("FileName: %s\n", dirData.cFileName); 
} 

Respuesta

1

Si está utilizando FindFirstFileEx, entonces usted debería ser capaz de especificar la opción _FINDEX_SEARCH_OPS::FindExSearchLimitToDirectories (para ser utilizado como parámetro en fSearchOpFindFirstFileEx) para limitar la primera búsqueda (y cualquier subsiguiente FindNextFile()) llama a los directorios.

+0

FindExSearchLimitToDirectories es bastante complejo, puede valer la pena mencionar algunas de las complejidades en su respuesta. Además, no soy 100%, resultará en una enumeración significativamente más rápida. ¿El filtrado se realiza en el nivel del sistema de archivos? –

+0

Según MSDN, "Si el sistema de archivos admite el filtrado de directorios, la función busca un directorio con el nombre especificado", así que supongo que está filtrado en el nivel del sistema de archivos. No estoy seguro del impacto en el rendimiento: no puedo perfilarlo ya que no tengo una máquina con Windows en casa. –

+0

Gracias por la respuesta, consulte mi edición donde no funciona con su método – user593747

1

Para ver un aumento en el rendimiento, debe haber soporte en el nivel del sistema de archivos. Si esto no existe, el sistema debe enumerar todos los objetos del directorio.

En principio, puede usar FindFirstFileEx especificando la bandera FindExSearchLimitToDirectories. Sin embargo, los estados de la documentación (énfasis mío):

Esta es una marca de advertencia. Si el sistema de archivos admite el filtrado de directorios, la función busca un archivo que coincida con el nombre especificado y también es un directorio. Si el sistema de archivos no admite el filtrado de directorios, este indicador se ignora silenciosamente.

Si se desea filtrar el directorio, este indicador se puede utilizar en todos los sistemas de archivos, pero como es un indicador de advertencia y solo afecta a los sistemas de archivos que lo admiten, la aplicación debe examinar los datos de atributo del archivo almacenados en el parámetro lpFindFileData de la función FindFirstFileEx para determinar si la función ha devuelto un identificador a un directorio.

Sin embargo, por lo que puedo decir, y la información es escasa, el indicador FindExSearchLimitToDirectories no es ampliamente compatible con los sistemas de archivos de escritorio.

Su mejor opción es usar FindFirstFileEx con FindExSearchLimitToDirectories. Aún debe realizar su propio filtrado en caso de que encuentre un sistema de archivos que no admita el filtrado de directorios en el nivel del sistema de archivos. Si tiene suerte y recurre a un sistema de archivos que sí lo admite, obtendrá el beneficio de rendimiento.

Cuestiones relacionadas