2011-11-08 20 views

Respuesta

67

Le sugiero que eche un vistazo a QDirIterator.

QDirIterator it(dir, QStringList() << "*.jpg", QDir::Files, QDirIterator::Subdirectories); 
while (it.hasNext()) 
    qDebug() << it.next(); 

Esto hace que el algoritmo sea más escalable. QDir::entryList() podría tomar repentinamente una gran cantidad de memoria cuando muchos archivos están almacenados en un solo directorio. No es bueno en pequeños dispositivos integrados.

+6

Perdí mucho tiempo porque no leía los documentos oficiales correctamente. Tenga en cuenta que "después de la construcción, el iterador se encuentra antes de la primera entrada del directorio. La función' next() 'devuelve la ruta a la siguiente entrada de directorio y avanza el iterador". Entonces su código que trata con los archivos debe venir después de 'it.next()'. –

5

Esto debería funcionar:

void scanDir(QDir dir) 
{ 
    dir.setNameFilters(QStringList("*.nut")); 
    dir.setFilter(QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks); 

    qDebug() << "Scanning: " << dir.path(); 

    QStringList fileList = dir.entryList(); 
    for (int i=0; i<fileList.count(); i++) 
    { 
     if(fileList[i] != "main.nut" && 
      fileList[i] != "info.nut") 
     { 
      qDebug() << "Found file: " << fileList[i]; 
     } 
    } 

    dir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); 
    QStringList dirList = dir.entryList(); 
    for (int i=0; i<dirList.size(); ++i) 
    { 
     QString newPath = QString("%1/%2").arg(dir.absolutePath()).arg(dirList.at(i)); 
     scanDir(QDir(newPath)); 
    } 
} 

Las diferencias con respecto a su código son los siguientes:

  • búsqueda en anchura en lugar de primera búsqueda en profundidad (no hay razón para ello, sólo lo prefieran)
  • Más filtros para evitar enlaces simbólicos
  • EntryList en lugar de EntryInfoList. No lo necesita si solo quiere el nombre del archivo.

lo probé y funciona correctamente, pero que observe lo siguiente:

  • Este proceso puede tardar mucho tiempo, por lo que considerar ejecutarlo a partir de hilos
  • Si hay recursividad profunda es posible que tenga problema con su pila
+0

A menos que me falta algo, ha cambiado la salida de su función. Él quiere la lista de todos los archivos en el directorio dado, mientras que su función solo imprimirá los nombres de los archivos, pero no proporcionará la lista. –

+0

No estaba llenando la lista de cadenas 'nutFiles', así que no incluí esta parte. Sin embargo, es bastante fácil modificar la función y obtener la lista de todos los archivos. – pnezis

3

Utilicé QDirIterator.

Así es como lo hago y lo fácil que era encontrar todas las rutas de archivos XML de forma recursiva absolutos muy rápido (Qt4.8.1):

// used to store the file paths 
filesStack = new QStack<QString>(); 

// I use a file dialog to let the user choose the root folder to search in 
if (fileDialog->exec() == QFileDialog::Accepted) { 
    QDir selectedDir(fileDialog->selectedFiles().first()); 
    selectedDir.setFilter(QDir::Files | 
          QDir::Dirs | QDir::NoDot | QDir::NoDotDot); 
    QStringList qsl; qsl.append("*.xml"); // I only want XML files 
    selectedDir.setNameFilters(qsl); 
    findFilesRecursively(selectedDir); 
} 

// this function stores the absolute paths of each file in a QVector 
void findFilesRecursively(QDir rootDir) { 
    QDirIterator it(rootDir, QDirIterator::Subdirectories); 
    while(it.hasNext()) { 
     filesStack->push(it.next()); 
    } 
} 

Gracias a todos por los consejos.

EDITAR: Pude haber omitido algunas declaraciones, ten cuidado.

+0

Tenga cuidado con los resultados de rendimiento de QDirIterator. –

Cuestiones relacionadas