2009-05-27 12 views
3

Was ist der sauberste Weg zur rekursiven Suche nach Dateien mit C++ und MFC?Rekursive Dateisuche mit C++ MFC?

EDIT: Bietet eine dieser Lösungen die Möglichkeit, mehrere Filter in einem Durchgang zu verwenden? Ich denke, mit CFileFind könnte ich nach *. * Filtern und dann benutzerdefinierten Code schreiben, um weiter in verschiedene Dateitypen zu filtern. Bietet irgendetwas integrierte Filter (dh. * .exe, *. Dll)?

EDIT2: Habe gerade eine offensichtliche Annahme, dass ich machte, dass macht meine vorherige EDIT ungültig. Wenn ich versuche, eine rekursive Suche mit CFileFind durchzuführen, muss ich *. * Als Platzhalter verwenden, da andernfalls Unterverzeichnisse nicht gefunden werden und keine Rekursion stattfindet. Das Filtern von verschiedenen Dateierweiterungen muss unabhängig voneinander getrennt behandelt werden.

+2

Die CFileFind-Klasse ist nur ein dünner Wrapper für die Windows-API-Funktionen FindFirstFile und FindNextFile. Diese enthalten keine Vorkehrungen für mehrere Platzhalter. –

Antwort

11

CFileFind verwenden.

Werfen Sie einen Blick auf diesen example von 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

Verwenden Sie Boost's Filesystem Implementierung!

Das rekursive Beispiel ist auch auf dem Dateisystem Homepage:

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

Ich weiß es nicht Ihre Frage, aber es ist auch einfach, ohne Rekursion durch ein 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' ist undefined – ahoo

+0

@ahoo oops. Zweifel, ich kann den Code, den ich dafür hatte, leicht finden, aber "nd" würde von 'ff.GetFileName()' oder 'ff.GetFilePath()' sein. So fügen Sie in jeder Iteration alle gefundenen Verzeichnisse zur Verzeichnisliste hinzu. [CFileFind] (http://msdn.microsoft.com/en-us/library/f33e1618.aspx) – crashmstr

2

Check out mit die recls Bibliothek - steht für rec ursive ls - das ist eine rekursive Suchbibliothek, die unter UNIX und Windows funktioniert. Es ist eine C-Bibliothek mit Anpassungen an verschiedene Sprachen, einschließlich C++. Aus dem Gedächtnis, können Sie es so etwas wie die folgenden verwenden:

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

Es wird mit abc in C beginnen alle .doc-Dateien und alle .xls-Dateien finden: \ mydir oder eines seiner Unterverzeichnisse.

Ich habe das nicht kompiliert, aber es sollte ziemlich nah an der Marke sein.

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

Es funktioniert nicht. Find.FindNextFile() gibt false zurück, auch wenn die Dateien im selben Verzeichnis vorhanden sind.``

+0

Vielleicht müssen Sie einen Platzhalter zu Ihrem Pfad hinzufügen? strSaveLog = "C: \\ mydir \\ *. *". Stellen Sie auch keine Frage an der Stelle, wo eine Antwort gehen sollte! – jacobsee