Dateien auf der Festplatte suchen

cesupa

Erfahrenes Mitglied
Hallo,

ich versuche gerade ein Such Programm zu schreiben das nach Dateien such soll, ich mache das ganze mit FindFirstFileEx() und FindNextFile(). Bisher habe ich es erfolgreich geschafft einen Ordner zu durchsuchen und Dateien und Ordner zu unterscheiden, jetzt möchte ich aber auch das mein Programm alle Unterordner mit durchsucht, also habe ich es so gemacht, dass wenn er einen Ordner gefunden hat, die suchfunktion nochmal aufruft mit dem neuen Ordner und diesen dann durchsucht, jedoch springt er immer wieder in den Ursprungsordner zurück und es gibt dann nach einiger Zeit einen Fehler von Windows.

Code:
int search_file(char pfad[256],char name[256])
{
    char searchpath[256];
    char newsearchpath[256];
    
    WIN32_FIND_DATA wfd;
    
    strcpy(searchpath,pfad);
    strcat(searchpath,name); //Suchpfad zusammensetzen
    cout<<"Durchsuche: "<<searchpath<<endl<<endl;

HANDLE hSearch = FindFirstFileEx((searchpath), FindExInfoStandard, &wfd, FindExSearchLimitToDirectories,NULL,FIND_FIRST_EX_CASE_SENSITIVE); //Erste Datei finden
 
cout<<wfd.cFileName<<endl; //und ausgeben


while(FindNextFile(hSearch,&wfd)) //Nächste Dateien finden
{
                                 if(wfd.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY) //Ist die gefundene Datei ein Ordner ?
                                 {
                                  cout<<wfd.cFileName<<"   <dir>   "<<endl;

                                  Sleep(2000); //abwarten damit ich sehe was passiert ;-)

                               if((wfd.cFileName!=".")&&(wfd.cFileName!="..")) //hier möchte ich verhindern das er in den Ursprungsordner zurückkehrt, jedoch ohne erfolg
                               {
                                  strcpy(newsearchpath,pfad);
                                  strcat(newsearchpath,wfd.cFileName);
                                  strcat(newsearchpath,"\\");        //neuen suchpfad zusammenstellen mit neuem Ordner
                                
                                
                                  search_file(newsearchpath,name); //Funktion mit neuem suchpfad aufrufen
                                  }
                                  
                                   }
                                   else
                                   {
                                 cout<<wfd.cFileName<<endl; //wenn Datei kein Ordner, trotzdem anzeigen
                                 }
                                 }
}

also ich hab schon versucht das Problem zu lösen, jedoch ohne erfolg :(

Ich hoffe ihr könnt mir weiterhelfen.

Gruß
cesupa
 
Deine if-Afrage für die "Punkte-Verzeichnisse" funktioniert so nicht. Du vergleichst an der Stelle nur Zeiger (die in der Konstellation nie überstimmen), aber keine Inhalte.

Du brauchst eigentlich nur zu prüfen, ob das erste Zeichen im String ein Punkt ist:
Code:
if( wfd.cFileName[0] != '.'  )
{
    // ...
}
 
Hi,

danke für die antwort, darauf müsste ich eigentlich selber kommen :)
Nun gibt es aber das Problem, das er einen Ordner durchsucht und sobald er einen Unterordner gefunden hat diesen durchsucht, jedoch beendet er nicht die Durchsuchung des vorherigen Ordners, sodass nicht alle Dateien gefunden werden. wie kann ich dieses Problem denn bewältigen ?

Danke für eure Antworten.

Gruß
cesupa
 
Änder mal die Zeile
Code:
if(wfd.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY)
in
Code:
if((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
da ein Ordner auch mehere Attribute besitzen kann.

Ich kenn jetzt FindFirstFileEx nicht, wenn die aber im Prinzip genauso ist wie FindFIrstFile
dann achte mal darauf, dass du alle Ordner / Dateien bei einer Suche erfasst!
Dazu solltest du standardmäßig einen Pfad durchsuchen, der am Ende ein Wildcart hat(zb, C:\Windows\*)
und dann jede gefunde Datei mit deinem Suchmuster vergleichst!
Ansonsten kann das mit FindFirstFile nicht klappen.
 
Hi.

Also mit Standard C++ hat das ganze wenig zu tun. Der C++ Standard besitzt keine Möglichkeit mit Verzeichnissen umzugehen weil das zu systemspezifisch ist. Unter Windows mit der Win32 API mußt du FindFirstFile et al. benutzen (obwohl es andere Bibliotheken gibt die ähnliche Funktionen anbieten).

Warum verwendest du eigentlich die FindFirstFileEx Funktion und insbesondere die FindExSearchLimitToDirectories Option? Diese Option ist in der MSDN markiert als "reserviert für zukünftige Benutzung" und hat demnach wahrscheinlich keine Wirkung - und wenn es die Wirkung hätte die man erwartet, würdest du damit schließlich keine Dateien finden.

Außerdem hast du vergessen, das HANDLE zum Schluß mit FindClose() wieder freizugeben. Dann kontrollierst du nicht ob die Funktion FindFirstFileEx überhaupt erfolgreich und das Handle gültig ist.

Desweiteren solltest du den Namen der Datei nicht zum Suchpfad hinzufügen, denn sonst findest du ja nicht alle Unterverzeichnisse, wenn diese nämlich nicht mit dem Namen der Datei übereinstimmen. Am besten solltest du an den Suchpfad ein Sternchen anhängen damit auch alle Dateien und Verzeichnisse gefunden werden.

Du überspringst zudem auch noch den ersten Eintrag im Verzeichnis. Ist das Absicht?

Code:
TCHAR szDir[MAX_PATH+1];

sprintf(szDir, "%s\\*", pfad);

HANDLE hsearch = FindFirstFile (szDir, &wfd);

if (hsearch != INVALID_HANDLE_VALUE) {
  do {
    if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
       // Unterverzeichnis.
       if ((strcmp(wfd.cFileName, ".") != 0) &&
           (strcmp(wfd.cFileName, "..") != 0)) {
          // neuen Pfad zusammenbauen, Funktion rekursiv aufrufen.
       }
    } else if (strcasecmp (wfd.cFileName, name) == 0) {
       // Datei gefunden...
    }
  } while (FindNextFile (hsearch, wfd));
  FindClose (hsearch);
} else {
  // Pfad nicht gefunden.
}
MCoder hat gesagt.:
Du brauchst eigentlich nur zu prüfen, ob das erste Zeichen im String ein Punkt ist:
Na, ich weiß nicht. Gibt es denn keine Dateien die mit einem Punkt anfangen?
 
deepthroat hat gesagt.:
Na, ich weiß nicht. Gibt es denn keine Dateien die mit einem Punkt anfangen?
Dateien schon, aber Verzeichnisse ( außer ./ und ../ ) mit vorangestelltem Punkt sind mir nicht bekannt. Die Entscheidung, ob Datei oder Verzeichnis, ist doch an der Programmposition schon erledigt. Oder ?
 
Hi,

@ deepthroat

Mein Projekt ist ja noch in der Entwicklungsphase :) , aber ich hab mal die Zeile

else if (strcasecmp (wfd.cFileName, name) == 0)

in mein Projekt eingefügt und bekam nur Ordner angezeigt, aber keine Dateien wenn ich die variable 'name' mit '*' belege, was genau macht denn die Funktion strcasecmp() :confused:

Vielen Dank für eure antworten.

Gruß
cesupa
 
cesupa hat gesagt.:
Hi,

@ deepthroat

Mein Projekt ist ja noch in der Entwicklungsphase :) , aber ich hab mal die Zeile

else if (strcasecmp (wfd.cFileName, name) == 0)

in mein Projekt eingefügt und bekam nur Ordner angezeigt, aber keine Dateien wenn ich die variable 'name' mit '*' belege, was genau macht denn die Funktion strcasecmp() :confused:
Die Funktion strcasecmp vergleicht 2 C-Strings miteinander und ignoriert dabei Groß- und Kleinschreibung. (siehe z.B. http://www.phim.unibe.ch/comp_doc/c_manual/C/MAN/strcasecmp.htm)

Das heißt mit der Funktion kannst du nur Dateien finden die exakt (außer Groß-/Kleinschreibung) mit dem Wert der Variablen "name" übereinstimmen. Du hast schließlich nicht gesagt das "name" eigentlich ein Muster enthält und nicht nur einen Dateinamen...

Du möchtest also vielmehr rekursiv einen Ordner nach einer oder mehreren Dateien durchsuchen die mit einem bestimmten Muster übereinstimmen.

Dann mußt du dir entweder selbst eine Funktion schreiben, die überprüft ob die gefundene Datei mit deinem Muster "name" übereinstimmt oder nicht.

Oder du mußt jedes Verzeichnis zweimal durchsuchen: zuerst nach der Datei (also
Code:
FindFirstFile ( suchpfad + '\\' + name, &hsearch);
usw.), danach nochmal nach allen Unterordnern (also
Code:
FindFirstFile (suchpfad + "\\*", &hsearch);
usw. ) damit du auch alle Unterordner findest.

PS: Der Code hier ist übrigens nur Pseudocode und dient nur als Veranschaulichung.
 

Neue Beiträge

Zurück