Dateien in einem Verzeichnis auflisten (FindFirstFile/FindNextFile)



  • Danke sieht wirklich übersichtlicher aus, wobei man statt dem Vergleich mit NULL auch den Wert invertieren kann.
    Jedoch eine Frage, lstrcmp() bedeutet jedesmal einen Funktionsaufruf (Daten auf den Stack, Daten wieder runter vom Stack), und das 2mal (2x lstrcmp) ist das wirklich sinnvoll, bei einer Funktion die so wie in meinem Fall beim Laufwerk C: über 100.000 mal aufgerufen wird, ich nehme an das die Funktion lstrcmp() zu groß ist als das der Compiler sie inline kreiert?

    Aber nochmal zum Thema kann jemand die Feststellung von mir bestätigen. Oder ist mein System nur eine "Ausnahme"?

    Gruß Alex



  • Alex_H schrieb:

    wobei man statt dem Vergleich mit NULL auch den Wert invertieren kann.

    So wurde die Funktion halt in der MSDN aufgerufen... Bin mir auch nicht sicher, ob ein !lstrcmp(...) schneller ist, da da dann ja wohl erst der Wert erst in einen bool umgewandelt werden muss, oder?!

    Alex_H schrieb:

    Jedoch eine Frage, lstrcmp() bedeutet jedesmal einen Funktionsaufruf (Daten auf den Stack, Daten wieder runter vom Stack), und das 2mal (2x lstrcmp) ist das wirklich sinnvoll, bei einer Funktion die so wie in meinem Fall beim Laufwerk C: über 100.000 mal aufgerufen wird, ich nehme an das die Funktion lstrcmp() zu groß ist als das der Compiler sie inline kreiert?

    Das stimmt allerdings auch wieder - käme also auf einen Test an 😉



  • Danke Flenders für die Arbeit die du mir gibst: 😉
    Also wie teste ich sowas?
    Ich dachte zuerst ich mache jeweils ein Programm lege es auf den Desktop und starte vor jedem Test den Rechner neu. Ich glaube dann bin ich den ganzen Tag beschäftigt.
    Da uns ja nicht die Geschwindigkeit der Festplatte interesiert sondern der Funktion, kann er die Daten ruhig aus dem Cache oder Ram lesen (welches genau weiß ich nicht). Ich habe alle unnötigen Dienste deaktiviert und den Rechner vom Internet getrennt. Zudem habe ich den Rechner in der Energieverwaltung auf Desktop gestellt(ja ich arbeite am Notebook AMD Sempron 3000+).
    Ich hab mich also in die Funktionen
    QueryPerformanceFrequency();
    QueryPerformanceCounter();
    eingelesen und werte die rufende Funktion aus.

    Ich habe beide Programme gestartet. und abwechselnd deins und meins 3 Partitionen durchsuchen lassen (141189 Dateien, 10003 Ordner), solange bis ich konstante Werte hatte.
    Dann habe ich 10 mal abwechselnd 10mal deins , 10 mal meins, durchsuchen lassen und die Werte mitgeschrieben. Insgesamt 200 Funktionsaufrufe

    Deine Lösung ergibt Ergebnisse von 1716 bis 1763 ms-> Durchschnitt 1740 ms
    Meine Lösung ergibt Ergebnisse von 1584 bis 1628 ms-> Durchschnitt 1624 ms

    ergibt eine Differenz von 116 ms. Was hälst Du von dem Ergebnis?

    Ach ja ich programmiere mit dem Borland Builder.

    So viel Arbeit und ich wollte den Rechner nur nach doppelte Dateien dursuchen lassen.

    Ich weiß aber immer noch nicht ob jemand den Fehler den ich in der FAQ vermute bestätigen kann.

    Gruß Alex



  • Alex_H schrieb:

    Danke Flenders für die Arbeit die du mir gibst: 😉

    Kein Problem, das mache ich doch gern 🤡

    Alex_H schrieb:

    Deine Lösung ergibt Ergebnisse von 1716 bis 1763 ms-> Durchschnitt 1740 ms
    Deine Lösung ergibt Ergebnisse von 1584 bis 1628 ms-> Durchschnitt 1624 ms

    ergibt eine Differenz von 116 ms. Was hälst Du von dem Ergebnis?

    Meintest du beim zweiten nicht "Meine Lösung" - also die von dir?!
    Ist zwar schon ein wenig, aber nicht die Welt - so ist das eben mit Code-Optimierungen meistens. Höhere Lesbarkeit führt oft zu höherem Zeitbedarf bzw. Zeitersparnis geht oft mit immer stärker unleserlichem Code einher. Leider.

    Alex_H schrieb:

    Ich weiß aber immer noch nicht ob jemand den Fehler den ich in der FAQ vermute bestätigen kann.

    Bei mir kommen komischerweise weder . noch .. im Ergebnis vor - sprich auch die ersten 2 Treffer, die rausgefiltert werden enthalten eigentlich schon sinnvolle Daten.



  • Den Quellcode in der FAQ hatte ich ja verbrochen, kann gut sein dass ich das "." und ".." mit php verwechselt hab oder so 😉



  • Danke flenders,
    habs sofort editiert (sch... copy paste).
    Mir ist es nur aufgefallen, weilich zuerst versucht habe es selbst zu implementieren und keine Ahnung von dem . bzw .. hatte Folge mein Programm hat sich ins unendliche rekursiv aufgerufen (wieso ist mein Stack nicht übergelaufen). Und beim Debuggen fiehl mir dann auf das er im Laufwerk c: zuerst o.g. Ordner gefunden hat, als er dann reinging kam dann der . und danach .. Ich habe es jetzt nochmal versucht und mir ist aufgefallen das er mit FindFirstFile einen Ordner zurückgibt wenn ich direkt im Laufwerk suche also C: ; 😨 ; oder E: wenn ich mit der Suche in einem Unterverzeichnis beginne kommt so wie Geeky das in den FAQ geschrieben hat . und dann .. naja wie auch immer.

    An Geeky:
    Du solltest nicht zu hart mit Dir ins Gericht gehen. 👍
    Wie es mir gerade scheint ist das von System zu System unterschiedlich. Siehe Flenders und mich.

    Gruß
    Alex

    PS: Wieso werden meine Texte immer so lang, erzähl ich zuviel?



  • Ich hatte es aber auch nur mit C:\* versucht - bei einem Unterverzeichniss kommt tatsächlich auch noch . und .. (wobei letzteres bei einem Root-Verzeichnis auch keinen Sinn macht)



  • Hmm, dann müsste man das in der FAQ besser mal ergänzen 😉



  • Mein Vorschlag:

    HANDLE fHandle;
    WIN32_FIND_DATA wfd;
    
    fHandle=FindFirstFile("C:\\*",&wfd);
    
    do
    {
    	// Eintrag nur behandeln, wenn es nicht . oder .. ist (werden nur bei Unterverzeichnissen mit zurückgeliefert)
    	if (!( (wfd.cFileName[0]=='.') && ( (wfd.cFileName[1]=='.' && wfd.cFileName[2]==0) || wfd.cFileName[1]==0 ) ))
    	{
    		if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    		{
    			MessageBox(0,wfd.cFileName,"Folgendes Verzeichnis wurde gefunden:",0);
    			// Datei ist keine, sondern ein Verzeichnis...
    			// Hier könnte man dasselbe nochmal machen, um auch die
    			// Unterverzeichnisse zu scannen ;-)
    		}
    		else
    		{
    			MessageBox(0,wfd.cFileName,"Folgende Datei gefunden:",0);
    		}
    	}
    }
    while (FindNextFile(fHandle,&wfd));
    
    FindClose(fHandle);
    


  • geeky schrieb:

    Hmm, dann müsste man das in der FAQ besser mal ergänzen 😉

    Deswegen habe ich dieses Thema nochmal zur Diskussion gebracht.

    zu flenders:
    Bedeutend schöner als mein Vorschlag, die Modifikation auf Do while ist super.
    Eine Variante wäre natürlich auch das lstrcmp(), aber das müßten einige villeicht erst noch nachlesen (mußte ich auch).

    Ich unterstütze Deinen Vorschlag 👍

    Gruß
    Alex


Anmelden zum Antworten