Recursively iterate over all the files in a directory and its subdirectories in Qt

前端 未结 4 1362
醉梦人生
醉梦人生 2020-12-07 15:47

I want to recursively scan a directory and all its sub-directories for files with a given extension - for example, all *.jpg files. How can you do that in Qt?

相关标签:
4条回答
  • 2020-12-07 16:23

    I used QDirIterator.

    Here's how I do it and how simple it was to find all XML absolute file paths recursively very fast (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());
        }
    }
    

    Thanks to everyone for the hints.

    EDIT: I may have omitted some declarations, beware.

    0 讨论(0)
  • 2020-12-07 16:26

    Another sample which indexes all files, using QFileInfo:

    void ID3Tab::scanDir( QDir dir )
    { QFileInfoList fil = dir.entryInfoList( QStringList( "*.mp3" ),
                                             QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks,
                                             QDir::Name | QDir::IgnoreCase );
      foreach ( QFileInfo fi, fil )
        indexFile( fi );
    
      QFileInfoList dil = dir.entryInfoList( QStringList( "*" ),
                                             QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks,
                                             QDir::Name | QDir::IgnoreCase );
      foreach ( QFileInfo di, dil )
        scanDir( QDir( di.absoluteFilePath() ) );
    }
    
    0 讨论(0)
  • 2020-12-07 16:28

    I suggest you have a look at QDirIterator.

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

    You could simply use QDir::entryList() recursively, but QDirIterator is simpler. Also, if you happen to have directories with a huge amount of files, you'd get pretty large lists from QDir::entryList(), which may not be good on small embedded devices.

    0 讨论(0)
  • 2020-12-07 16:28

    This should work :

    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));
        }
    }
    

    The differences from your code are the following:

    • Breadth first search instead of depth first search (no reason for it, I just prefer it)
    • More filters in order to avoid sym links
    • EntryList instead of EntryInfoList. You don t need if you just want the name of the file.

    I tested it and it works correctly, but notice the following:

    • This may take a lot of time, so consider running it from thread
    • If there is deep recursion you may have problem with your stack
    0 讨论(0)
提交回复
热议问题