Spezifische Datei rekursiv in Laufwerk suchen
-
Hallo,
erstmal vorweg -> bin relativ neu in der C++ programmierung und komme eher aus dem Linux perl bereich, daher bitte ich um nachsicht

Also zu meinem Problem:
Ich möchte gerne eine Datei rekursiv in einem Laufwerk suchen lassen.
Habe schon einige Threads dazu gelesen hier im Forum und mir auch schon die
passenden MSDN einträge dazu reingepfiffen
jedoch bleibe ich an einem punkt immer hängen.Hier erstmal der Code damit Ihr wißt wovon ich überhaupt rede !
void __fastcall TForm1::StartSearch1Click(TObject *Sender) { // Definiere Variablen HANDLE fHandle; WIN32_FIND_DATA wfd; int gefunden; LMDBrowseDlg1->Execute(); if (LMDBrowseDlg1->SelectedFolder=="") { ShowMessage("Nothing Selected"); } else { LMDBrowseDlg1->SelectedFolder=LMDBrowseDlg1->SelectedFolder+"\\*"; ShowMessage(LMDBrowseDlg1->SelectedFolder); // Zur Kontrolle LMDBrowseDlg1->SelectedFolder=LMDBrowseDlg1->SelectedFolder+"\\*"; // Erste Datei holen: // aufgrund von "alten Zeiten" ist das erste immer ein "." // kann also ignoriert werden. fHandle=FindFirstFile(LMDBrowseDlg1->SelectedFolder.c_str(),&wfd); // Ergebnis Nummer 2 ist auch uninteressant (ist ".."): FindNextFile(fHandle,&wfd); gefunden = 0; while (gefunden < 1) { FindNextFile(fHandle,&wfd); if (lstrcmpi(wfd.cAlternateFileName,"meinfile.txt")) { ListBox1->Items->Append(wfd.cFileName); // Hier soll er dann die gefundene Datei offnen,ein string // auslesen und und und } if (fHandle == INVALID_HANDLE_VALUE) { ShowMessage("Sorry nothing found !"); gefunden = 1; } } FindClose(fHandle); } }Ich klicke in meinem Menu auf Start Search...ein VerzeichnisBrowseDialog öffnet sich und ich gebe an von wo er anfangen soll zu suchen nach meinem file (meinfile.txt) in meinem fall ist das z.B D:\test\ wo allerdings nur ein ordner drin ist der "dir1" heißt. in dem "dir1" liegt dann aber die meinfile.txt drin
Problem 1: "if (lstrcmpi(wfd.cAlternateFileName,"meinfile.txt"))" scheint immer true zurück zu liefern, selbst wenn cAlternateFileName = "dir1" ist ????????
Problem 2: Er sucht nicht weiter rekursiv...sondern stopt dann und macht nicht weiter ???
Vielen Dank schon mal im voraus für eure Hilfe...bin echt am verzweifeln.
-
Hi,
Problem 1: versuch es mal so:if ( lstrcmpi(wfd.cAlternateFileName,"meinfile.txt") == 0 );Problem 2: klar macht er nicht weiter, mit dieser Methode kannst Du immer nur ein Verzeichniss durchsuchen, also am besten Du machst eine Funktion draus mit 2 Parametern, der erste ist das Gesuchte File , der Zweite das Verzeichniss in dem Du Dich gerade befindest.
Anschließend fängst Du in der Funktion drin das suchen an, sobald Du ein Verzeichniss gefunden hast (siehe Hilfe zu FindNextFile()) musst Du den zweiten Parameter um das gefundene Verzeichniss erweitern und die ganze Funktion nochmal aufrufen (also rekursiv).Das Problem dabei ist dass Du bei einem Fehler evtl. in einer Endlosschleife endest, also schön Haltepunkte setzen und die Variablen überwachen

Gruß
-
Also:
if ( lstrcmpi(wfd.cAlternateFileName,"meinfile.txt") == 0 );bringt nothing..spuckt nachwievor das erste gefundene File/dir aus.
Desweiteren frage ich mich dann wozu die while schleife dann dient ?
Generell nahm ich eigentlich an das FindFirstFile & FindNextFile eigentlich rekursiv sucht und durch den verzeichnisbaum geht (automatisch !)Völlig verwirrt nun
-
StarGate schrieb:
if ( lstrcmpi(wfd.cAlternateFileName,"meinfile.txt") == 0 );bringt nothing..spuckt nachwievor das erste gefundene File/dir aus.
Ich kann mir irgendwie kaum vorstellen, dass sich der Code mit "== 0" genau so verhällt, wie bei "!= 0" bzw. weggelassenem "== 0"

StarGate schrieb:
Desweiteren frage ich mich dann wozu die while schleife dann dient ?
Du bekommst in jedem Durchlauf einen Verzeichnis-Eintrag zurückgeliefert (entsprechend dem in FindFirstFile angegebenen Filter - also evtl. auch . und ..)
StarGate schrieb:
Generell nahm ich eigentlich an das FindFirstFile & FindNextFile eigentlich rekursiv sucht und durch den verzeichnisbaum geht (automatisch !)
Nein, dem ist nicht so. Es wird generell nur das eine angegebene Verzeichnis untersucht (und keine Unterverzeichnisse). Mit der Rekursion gibt es allerdings afaik manchmal Probleme, dass er nach dem zurückkehren nicht an der richtigen Stelle im Verzeichnis weitersucht. Wenn ich es richtig in Erinnerung habe, sollte man sich die Unterverzeichnisse z.B. in einem vector zwischenspeichern und dann die einzelnen Verzeichnisse immer komplett abarbeiten, bevor man zum nächsten geht -> Forensuche bzw. Google
-
..hmmm kann mich eigentlich nur dem flenders anschließen was Dein
if ( lstrcmpi(wfd.cAlternateFileName,"meinfile.txt") == 0 );Problem betrifft...
ich habe es damals so gelöst:
if (strcmp(wfd.cFileName,"meinfile.txt"))das sollte funktionieren ! sonst hast Du irgendwo ein anderes Problem...
und hier eine rekursive Funktion zum durchsuchen aller Unterverzeichnisse:
void SearchEntrys(CString sCurDir) { WIN32_FIND_DATA FileData; HANDLE hSearch; CString item; item.Format("%s\\*", sCurDir); // Nach Einträgen suchen (Ordner / Dateien) hSearch = FindFirstFile(item, &FileData); if (hSearch == INVALID_HANDLE_VALUE) return; // Nichts gefunden do { // Is it a directory ? if ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { SearchEntrys(item); // Aktionen hier einfügen, wenn es ein Ordner ist. } else { // Aktionen hier einfügen, wenn es eine Datei ist. } } while (FindNextFile(hSearch, &FileData)); FindClose(hSearch); }mach was draus !!

-
Erstmal vielen vielen dank für eure Hilfe !!! Letzter Post bezgl. der Such Funktion schein prima zusein jedoch habe ich gerade das problem, das ich nicht herausfinden kann welchen include ich brauch unterm Borland C++ Builder 6 um den CString zu nutzen

Gruß
StarGate
-
Du kannst anstatt CString auch Ansistring verwenden,
es ändert sich dann:item.Format("%s\\*", sCurDir);in
item += "\\*"; // kann sein das es einfache Anführungsstriche sein müßen..und beim Aufruf anstatt
FindFirstFile(item, &FileData);das hier:
FindFirstFile(item.s_str(), &FileData);desweiteren befindet sich noch ein kleiner Fehler in der Funktion aber den findest Du sicher auch selbst...

Gruß
-
was habe ich denn da wieder geschrieben ..
AnsiString <- schreibt man sound der letzte C++ Code muss natürlich so lauten :
FindFirstFile(item.c_str(), &FileData);
-
Nochmals ein dicken dank an dich !! Vorallem das du/generell das Forum das Ihr immer so viel geduld mit newbees habt !!
Jedoch irgendwie haut das mit deiner Rekursiven version nicht hin, ich bekomme irgendwie kein reply mehr, eher Programm abstürze...
Die Fehler in der Routine habe ich selber gefunden.
Du hast geschrieben ich sollte :
item.Format("%s\\*", sCurDir);durch
item += "\\*";ersetzen...jedoch woher bekommt "item" dann sein wert zugeteilt wenn er in deiner schleife dann sich selbst nochmal aufruft ?
if ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { SearchEntrys(item); // Aktionen hier einfügen, wenn es ein Ordner ist. }Irgendwie peil ich das ganze mit der C++ Syntax nicht....perl is da VIEL einfacher

-
Wenn du die Funktion rekursiv aufrufen willst, dann darfst du nicht direkt das \* an den String hängen, sondern musst ihn vorher kopieren, damit du für den "inneren Funktionsaufruf" noch den unveränderten String hast. An diesen musst du dann aber noch den Namen des aktuell eingelesenen Verzeichnis-Eintrags anhängen

Schau dir auch mal diesen Artikel an: Templated Directory Walker
-
Also so sieht derzeit meine Funktion aus und es klappt nicht

void SearchEntrys(AnsiString sCurDir) { WIN32_FIND_DATA FileData; HANDLE hSearch; AnsiString item; sCurDir += "\\*"; // Nach Einträgen suchen (Ordner / Dateien) hSearch = FindFirstFile(sCurDir.c_str(), &FileData); if (hSearch == INVALID_HANDLE_VALUE) { ShowMessage(GetLastError()); return; // Nichts gefunden } do { // Skip "." Directory if (strcmp(FileData.cFileName,".") & FileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) { continue; } // Skip ".." Directory if (strcmp(FileData.cFileName,"..") & FileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) { continue; } // Ist es ein Directory ? if ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { item = sCurDir; item = item + "\\" + FileData.cFileName; SearchEntrys(item); } if (lstrcmpi(FileData.cFileName,"meinfile.txt")) { ShowMessage("Found a File"); } } while (FindNextFile(hSearch, &FileData)); FindClose(hSearch); }Seufz, C++ macht mich fertig
-
Schau dir mal die Pfade nach dem Zusammensetzen an. Dann wirst du merken, dass du sie falsch zusammensetzt
