2009-05-27 6 views
3

Quel est le moyen le plus propre de rechercher récursivement des fichiers en utilisant C++ et MFC?Recherche de fichier récursive en utilisant C++ MFC?

EDIT: Est-ce que l'une de ces solutions offre la possibilité d'utiliser plusieurs filtres en une seule passe? Je suppose avec CFileFind que je pourrais filtrer sur *. *, Puis écrire du code personnalisé pour filtrer davantage dans différents types de fichiers. Est-ce que quelque chose offre des filtres multiples intégrés (par exemple. * .exe, *. Dll)?

EDIT2: Je viens de réaliser une supposition évidente que je faisais qui rend mon précédent EDIT invalide. Si j'essaie de faire une recherche récursive avec CFileFind, je dois utiliser *. * Comme caractère générique car sinon les sous-répertoires ne seront pas comparés et aucune récursivité n'aura lieu. Donc le filtrage sur différentes extensions de fichiers devra être géré séparément indépendamment.

+2

La classe CFileFind est juste une enveloppe fine sur les fonctions de l'API Windows FindFirstFile et FindNextFile. Ceux-ci ne prévoient aucune disposition pour plusieurs caractères génériques. –

Répondre

11

En utilisant CFileFind.

Jetez un oeil à cette example de MSDN:

void Recurse(LPCTSTR pstr) 
{ 
    CFileFind finder; 

    // build a string with wildcards 
    CString strWildcard(pstr); 
    strWildcard += _T("\\*.*"); 

    // start working for files 
    BOOL bWorking = finder.FindFile(strWildcard); 

    while (bWorking) 
    { 
     bWorking = finder.FindNextFile(); 

     // skip . and .. files; otherwise, we'd 
     // recur infinitely! 

     if (finder.IsDots()) 
     continue; 

     // if it's a directory, recursively search it 

     if (finder.IsDirectory()) 
     { 
     CString str = finder.GetFilePath(); 
     cout << (LPCTSTR) str << endl; 
     Recurse(str); 
     } 
    } 

    finder.Close(); 
} 
4

Utilisez l'implémentation Boost's Filesystem!

L'exemple récursif est même sur la page d'accueil du système de fichiers:

bool find_file(const path & dir_path,   // in this directory, 
       const std::string & file_name, // search for this name, 
       path & path_found)   // placing path here if found 
{ 
    if (!exists(dir_path)) return false; 
    directory_iterator end_itr; // default construction yields past-the-end 
    for (directory_iterator itr(dir_path); 
     itr != end_itr; 
     ++itr) 
    { 
    if (is_directory(itr->status())) 
    { 
     if (find_file(itr->path(), file_name, path_found)) return true; 
    } 
    else if (itr->leaf() == file_name) // see below 
    { 
     path_found = itr->path(); 
     return true; 
    } 
    } 
    return false; 
} 
2

Je sais que ce n'est pas votre question, mais il est aussi facile à Tô sans récursivité en utilisant un CStringArray

void FindFiles(CString srcFolder) 
{ 
    CStringArray dirs; 
    dirs.Add(srcFolder + "\\*.*"); 

    while(dirs.GetSize() > 0) { 
    CString dir = dirs.GetAt(0); 
    dirs.RemoveAt(0); 

    CFileFind ff; 
    BOOL good = ff.FindFile(dir); 

    while(good) { 
     good = ff.FindNextFile(); 
     if(!ff.IsDots()) { 
      if(!ff.IsDirectory()) { 
      //process file 
      } else { 
      //new directory (and not . or ..) 
      dirs.InsertAt(0,nd + "\\*.*"); 
      } 
     } 
    } 
    ff.Close(); 
    } 
} 
+0

'nd' est indéfini – ahoo

+0

@ahoo oops. Doute je peux facilement trouver le code que j'avais pour cela, mais 'nd' serait de' ff.GetFileName() 'ou' ff.GetFilePath() '. Ainsi, à chaque itération, vous ajoutez tous les répertoires trouvés à la liste 'dirs'. [CFileFind] (http://msdn.microsoft.com/fr-fr/library/f33e1618.aspx) – crashmstr

2

Check out la bibliothèque recls - signifie rec ursive ls - qui est une bibliothèque de recherche récursive qui fonctionne sous UNIX et Windows. C'est une bibliothèque C avec des adaptations à différents langages, y compris C++. De mémoire, vous pouvez l'utiliser quelque chose comme ce qui suit:

using recls::search_sequence; 


CString dir = "C:\\mydir"; 
CString patterns = "*.doc;abc*.xls"; 
CStringArray paths; 
search_sequence files(dir, patterns, recls::RECURSIVE); 

for(search_sequence::const_iterator b = files.begin(); b != files.end(); b++) { 
    paths.Add((*b).c_str()); 
} 

Il y trouverez tous les fichiers .doc, et tous les fichiers .xls commençant par abc dans C: \ mydir ou l'un de ses sous-répertoires.

Je n'ai pas compilé ceci, mais il devrait être assez proche de la marque.

-1
CString strNextFileName , strSaveLog= "C:\\mydir"; 
Find.FindFile(strSaveLog); 
BOOL l = Find.FindNextFile(); 
if(!l) 
    MessageBox(""); 
strNextFileName = Find.GetFileName(); 

Cela ne fonctionne pas. Find.FindNextFile() retourne false même si les fichiers sont présents dans le même répertoire``

+0

Peut-être que vous devez ajouter un caractère générique à votre chemin? strSaveLog = "C: \\ mydir \\ *. *". Aussi, ne posez pas de question à l'endroit où une réponse devrait aller! – jacobsee

Questions connexes