2011-11-08 9 views

Odpowiedz

67

Proponuję rzucić okiem na QDirIterator.

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

Dzięki temu algorytm jest bardziej skalowalny. QDir::entryList() może zająć nagle dużą ilość pamięci, gdy wiele plików jest przechowywanych w jednym katalogu. Niedobrze na małych urządzeniach wbudowanych.

+6

Zmarnowałem dużo czasu, ponieważ nie czytałem oficjalnych dokumentów. Uwaga: "Po zakończeniu budowy, iterator znajduje się przed pierwszym wpisem do katalogu Funkcja' next() 'zwraca ścieżkę do następnej pozycji katalogu i przesuwa iterator." Twój kod, który zajmuje się plikami, powinien pojawić się po 'it.next()'. –

5

To powinno działać:

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

Różnice z kodu są następujące:

  • przeszukiwanie wszerz zamiast głębokość pierwszego wyszukiwania (bez względu na to, po prostu wolą)
  • Więcej filtrów w celu uniknięcia linków symycznych
  • Element EntryList zamiast EntryInfoList. Nie potrzebujesz, jeśli chcesz tylko nazwę pliku.

ja testowałem to i działa poprawnie, ale występują następujące objawy:

  • To może zająć dużo czasu, więc rozważyć uruchomienie go z nici
  • Jeśli jest głęboko rekurencji może masz problem ze swoim stosem
+0

O ile czegoś nie brakuje, zmieniłeś wyjście swojej funkcji. Chce mieć listę wszystkich plików w podanym katalogu, a twoja funkcja wydrukuje tylko nazwy plików, ale nie dostarczy listy. –

+0

Nie wypełniał listy ciągów "nutFiles', więc nie zawarłem tej części. Łatwo jest jednak zmodyfikować funkcję i uzyskać listę wszystkich plików – pnezis

3

Użyłem QDirIterator.

Oto jak to zrobić i jak łatwo było znaleźć wszystkie ścieżki bezwzględne plik XML rekurencyjnie bardzo szybko (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()); 
    } 
} 

Dzięki wszystkim za podpowiedzi.

EDYCJA: Mogłem pominąć niektóre deklaracje, uważaj.

+0

Wystrzegaj się trafień wydajnościowych z QDirIterator. –

Powiązane problemy