Frage zu FindFirstFile und FindNextFile



  • Hallo,

    mit den Funktionen FindFirstFile und FindNextFile ist es ja möglich sich die Dateien eines Verzeichnisses auflisten zu lassen. Nehmen wir mal an ich suche alle *.txt Dateien in dem Verzeichniss C:\TEMP. Also rufe ich fHandle = FindFirstFile("C:\\TEMP\*.txt\0", &wfd); auf und werte aus ob der gefundene Handle eine Datei oder ein Verzeichniss ist. Somit besitze ich dann einen gültigen Handle auf die erste gefundene Datei mit der Endung .txt. den Dateinamen bekomme ich über wfd.cFileName. Wenn ich nun an dieser Stelle abbreche weil ich den Dateinamen irgendwie weiterverarbeiten muss etc., wie muss ich nun FindNextFile aufrufen um die nächste Datei nach der vorhergefundenen zu erhalten? Muß ich etwa nochmals bei FindFirstFile mit den Wildcards beginnen und solange FindNextFile aufrufen bis ich die vorherige Datei gefunden habe und somit folgt, daß der nächste Aufruf von FindNextFile mir die nächste Datei liefert, oder wie gehe ich da am geschicktesten vor?



  • FindFirstFile gibt dir ja ein Handle zurück.

    Dieses Handle kannst du der Funktion FindNextFile als ersten Parameter übergeben, somit wird automatisch ab der richtigen Stelle weitergesucht.



  • Aber woher weiß FindNextFile was ich irgendwann mal als Filter/Wildcard angegeben habe um mit FindFirstFile die erste Datei zu finden?
    Ich hab da mal einen funktionierenden Code geschrieben, die Profis unter euch werden sich warscheinlich die Haare raufen, weil die Performance auf der Strecke bleibt, da die Funktion immer wieder von Anfang an beginnt:

    boolean File_ListFilesinDirectory(char *directory, char *wildcards, char *findname){
    
    	HANDLE		fHandle;
    	WIN32_FIND_DATA	wfd;
    	char			searchstring[MAX_FILE];
    	int			dir_len;
    
    	dir_len = strlen(directory);
    	if(strrchr(directory, '\\') == directory + dir_len){					//falls ein "\" am Ende steht löschen wir es, nur zur Sicherheit
    		directory[dir_len - 1] = 0;
    	}
    	sprintf(searchstring, "%s\\%s", directory, searchname);
    	fHandle = FindFirstFile(searchstring, &wfd);
    	while(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
    		if(FindNextFile(fHandle, &wfd) == 0){
    			return FALSE;
    		}
    	}
    	if(findname[0] != 0){
    		do{
    			if(strcmp(findname, wfd.cFileName) == 0){
    				break;
    			}
    		}while(FindNextFile(fHandle, &wfd));
    		if(FindNextFile(fHandle, &wfd) == 0){
    			return FALSE;
    		}
    		while(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
    			if(FindNextFile(fHandle, &wfd) == 0){
    				return FALSE;
    			}
    		}
    	}
    	strncpy(findname, wfd.cFileName, MAX_FILE);
    	findname[MAX_FILE-1] = 0;
    	FindClose(fHandle);
    	return TRUE;
    }
    

    ok hier der Aufruf zur Funktion:

    char		findname[MAX_FILE];
    
    	memset(&findname, 0, sizeof(findname));			
    	while(File_ListFilesinDirectory("C:\\Projekte\\Test", "*.h", findname)){
    		OUTPUT(findname);						//Hilfsfenster zur Anzeige
    	}
    

    Wie gesagt, funktionieren tut der Code, es werden alle Dateinen aufgelistet die im definierten Verzeichniss der Wildcardvorgabe entsprechen, aber ich bin mir sicher daß die Cracks unter euch das viel geschickter lösen. Also Verbesserungsvorschläge werden dankend angenommen.



  • Ok, ist mir doch beim Kopieren ein Fehler unterlaufen:

    sprintf(searchstring, "%s\\%s", directory, searchname);
    

    muss heissen

    sprintf(searchstring, "%s\\%s", directory, wildcards);
    


  • Also entweder recursiv die bearbeitungsfunktion aufrufen oder das Ergebniss erstmal in eine eigene Liste speichern.

    FindNextFile bezieht sich auf das Handle von FindFirstFile.
    Wenn FindFirstFile "zerstört" wird, ist das Handle ungültig.

    Stefan



  • StefanKittel schrieb:

    Wenn FindFirstFile "zerstört" wird, ist das Handle ungültig.

    Das war die info die mir gefehlt hat. Naja dann lass ich meinen code mal so.



  • StefanKittel schrieb:

    FindNextFile bezieht sich auf das Handle von FindFirstFile.
    Wenn FindFirstFile "zerstört" wird, ist das Handle ungültig.

    FindFirstFile ist eine Funktion und kann nicht zerstört werden.
    Das Handle wird mit FindClose weider freigegeben. Danach ist es ungültig.

    MSDN, FindClose: http://msdn.microsoft.com/en-us/library/aa364413.aspx

    Simon



  • Mein Verständnissproblem ist folgendes, bei FindFirstFile gibt man die Suchparameter vor, hat man nun eine Datei gefunden und bricht ab. Welchen Aufruf muß man durchfüheren, um die zuerst festgelegten Suchparameter beizubehalten, aber die Suche bei der zuletzt gefundenen Datei weiterzuführen? Ist es wirklich möglich, daß man sich da von Anfang an wieder durchparsen muß, in etwa so, wie ich es in meinem Code anwende? Bei wenigen Dateien ist das ja unerheblich aber bei vielen Dateien zieht sich das doch bestimmt.



  • In diesem Fall musst Du Dir das von FindFirstFile zurückgegebene Handle merken. Alle nachfolgenden Aufrufe passieren dann mit FindNextFile. FindClose darf erst dann aufgerufen werden, wenn die Suche beendet ist.



  • theta schrieb:

    FindFirstFile ist eine Funktion und kann nicht zerstört werden.

    Das war mir schon klar. bin ja nicht rambo

    theta schrieb:

    Das Handle wird mit FindClose weider freigegeben. Danach ist es ungültig.

    das meinte ich. wenn er die suche abbricht oder beendet und dann muss er findclose aufrufen, kann er nicht weitersuchen. wie auch.



  • Ist es aber nicht auch so, daß nicht nur der letzte Handle gemerkt werden muß, sondern auch die WIN32_FIND_DATA, die ja bei FindFirstFile gefüllt wurde. Ich weiß nicht ob meine Vermutung stimmt, aber ich denke daß FindNextFile nicht nur die Struktur neu füllt, sondern auch eine schon gefüllte Struktur beim Aufruf benötigt?



  • @Mad Marco

    Wieso probierst du es nicht aus? Zu Faul? Zu einfach?
    Es gibt in VisualStudio ein Trick.. mit diesem wunderlichen und sehr nützlichen Trick lässt sich alles anschauen während das Programm läuft..

    Der Trick nennt sich... ooooooh wär hät es gedacht..."Debuggen"

    😉


Log in to reply