Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Findfirst...Findnext funktioniert nicht 100%ig (https://www.delphipraxis.net/87966-findfirst-findnext-funktioniert-nicht-100ig.html)

scrat1979 8. Mär 2007 07:41


Findfirst...Findnext funktioniert nicht 100%ig
 
Ich habe ein Problem mit einer Komponente, die ich im Moment schreibe. Keine Angst, es handelt sich um ein "Object-Pascal" - PRoblem.

Die Komponente macht im Prinzip nichts anderes wie alle Dateien in einem Verzeichnis aufzulisten, wobei auch Unterverzeichnisse mitberücksichtigt werden. Nun das Problem: Die PRozedur arbeitet perfekt, bis auf eine Kleinigkeit: Stellt man z.B. Mask auf '*.pas' funktioniert die Prozedur nur. wenn im ersten Verzeichnis auch mind. eine .pas-Datei vorhanden ist ( Da ja nur dann FindFirst = 0 ist ). Hat mir jemand evtl. ein Workaround dafür??

Danke im Voraus,

SCRaT

Delphi-Quellcode:
procedure TMyFileSearch.DoSearch(InitDir : String);
var SR     : TSearchRec;
     S     : String;
begin
 if FindFirst(InitDir + FMask, faAnyFile, sr) = 0 then
    begin
      repeat
        // '.' und '..' nicht beachten
        if (SR.Name <> '.') and (SR.Name <> '..') then Begin;
          // Wenn kein Verzeichnis
          if (SR.Attr and faDirectory) = 0 then Begin
            IF FFullPath Then FFileList.Add(InitDir + SR.Name)
                         Else FFileLIst.Add(SR.Name);
          end else begin
            // Wenn Verzeichnis
            IF FFullpath Then S := InitDir + SR.Name
                         Else S := SR.Name;

            if FMarkDirs then S := '[' + S + ']';

            IF FShowDirs Then FFileList.Add(S);
            if FSubDirs Then DoSearch(InitDir + SR.Name + '\');
          end;
        End;
      until FindNext(sr) <> 0;
      FindClose(sr);
 end;
End;
EDIT: Statt "IF FindFirst..." nur "FindFirst..." zu schreiben funktioniert leider nicht :-(

Klaus01 8. Mär 2007 07:47

Re: Findfirst...Findnext funktioniert nicht 100%ig
 
Guten Morgen,

schau Dir bitte einmal diesen Thread aus der CodeLib an, rekursiv heißt da der Ansatz.

Grüße
Klaus

scrat1979 8. Mär 2007 07:58

Re: Findfirst...Findnext funktioniert nicht 100%ig
 
Dankeschön, aber genau das ist das Problem. Mein Prinzip ist ja dasselbe. Übrigens wird ja auch bei mir schon rekursiv gesucht :P

Delphi-Quellcode:
[...]
     if FSubDirs Then DoSearch(InitDir + SR.Name + '\');
[...]
Das Hauptproblem ist nur, dass die Prozedur erst gar nicht durchlaufen wird, wenn eine entsprechende DAtei im STARTVERZEICHNIS nicht gefunden wurde.

Beispiel 1: Suchstart in D:\TEST mit Mask = '*.INI'

D:\TEST\TEST1.TXT
D:\TEST\TEST2.TXT
D:\TEST\TEST1.INI <--
D:\TEST\MYFILE.DAT
D:\TEST\TESTDIR\CONFIG.INI <--

dies funktioniert, da im Startverzeichnis eine .INI-DAtei vorhanden ist.

Beispiel 1: Suchstart in D:\TEST mit Mask = '*.INI'

D:\TEST\TEST1.TXT
D:\TEST\TEST2.TXT
D:\TEST\MYFILE.DAT
D:\TEST\TESTDIR\CONFIG.INI <-- wird nicht gefunden

dies funktioniert NICHT, da im Startverzeichnis KEINE .INI-DAtei vorhanden ist. Somit kommt die Prozedur erst gar nicht an den Punkt um die Verzeichnisse rekursiv aufzurufen.

SCRaT

Klaus01 8. Mär 2007 08:15

Re: Findfirst...Findnext funktioniert nicht 100%ig
 
Delphi-Quellcode:
  if Recurse then
    if FindFirst(RootFolder + '*.*', faAnyFile, SR) = 0 then   //<-- geht durch den Verzeichnisbaum
    try
      repeat
        if SR.Attr and faDirectory = faDirectory then
            // --> ein Verzeichnis wurde gefunden
            //   der Verzeichnisname steht in SR.Name
            //   der vollständige Verzeichnisname (inkl. darüberliegender Pfade) ist
            //       RootFolder + SR.Name
          if (SR.Name <> '.') and (SR.Name <> '..') then
            FindAllFiles(FileList, RootFolder + SR.Name, Mask, Recurse);
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
  if FindFirst(RootFolder + Mask, faAnyFile, SR) = 0 then
  try
    repeat
      if SR.Attr and faDirectory <> faDirectory then
      begin
          // --> eine Datei wurde gefunden
          //   der Dateiname steht in SR.Name
          //   der vollständige Dateiname (inkl. Pfadangabe) ist
          //       RootFolder + SR.Name
        FileList.Add(RootFolder + SR.Name);
      end;
    until FindNext(SR) <> 0;
  finally
    FindClose(SR);
  end;
Da es sich um rekursion handelt , wird erst zum tiefsten Punkt der Verzeichnisstruktur gewechselt (FindFirst und FindNext mit Maske *.*) dort wird dann FindFirst und FindNext mit der Suchmaske ausgeführt.

Dies ist bei Dir nicht der Fall, bei Dir wird zuerst nach einem File mit der Suchmaske *.ini gesucht.
Ist das erfolglos wird nicht nach Unterverzeichnissen gesucht.
Du müsstes Dein Funktion etwas umbauen.

Grüße
Klaus

DelphiKlaus 8. Mär 2007 08:17

Re: Findfirst...Findnext funktioniert nicht 100%ig
 
Hallo,

wenn Du Ini-Dateien suchst und dann mit FindFirst (...) = 0 prüfst, ob Du eine gefunden hast, ist es doch kein Wunder, dass Du garnichts findest, wenn keine Ini-Datei vorhanden ist. Such mal nach '*.*' und werte selbst aus, ob es eine Ini-Datei oder ein Verzeichnis ist. Dann sollte es funktionieren.

Klaus

Gremlin 8. Mär 2007 08:22

Re: Findfirst...Findnext funktioniert nicht 100%ig
 
Morgen,

dein Problem tritt doch nur auf, wenn du eine Dateimaske (zb. *.pas)
übergeben hast und keine passenden Dateien, aber mögliche andere Dateien
in evetuell vorhandenen Unterverzeichnissen vorkommen?!

Entweder suchst du immer nach '*.*' und maskierst selbst aus und kannst
somit auch die Unterverzeichnisse berücksichten (ich kann dir jetzt nichts
über den Overhead der FindFirst-Routine sagen) oder du berücksichtigst
beim Beginn bzw. Ende der Suche die Dateimaske. Wenn diese <> '*.*' ist,
dann musst du noch extra die Unterverzeichnisse im Verzeichnis suchen
(faDirectory) und diese zusätzlich untersuchen.

Gruss Gremlin

scrat1979 8. Mär 2007 08:33

Re: Findfirst...Findnext funktioniert nicht 100%ig
 
Hmmm, okay. Ich glaube ich werde dann wohl ALLE Dateien auflisten und die entsprechenden Dateien dann selbst filtern!! Danke!

SCRaT

EDIT: Hat so funktioniert. Vielen Dank für die Tips.

jbg 8. Mär 2007 12:06

Re: Findfirst...Findnext funktioniert nicht 100%ig
 
Zitat:

Zitat von scrat1979
Hmmm, okay. Ich glaube ich werde dann wohl ALLE Dateien auflisten und die entsprechenden Dateien dann selbst filtern!!

Übrigens, die FindFirstFile/FindNextFile API Funktionen, die von FindFirst/FindNext aufgerufen werden liefern immer alle Dateien. Da kann man nicht auf eine Dateimaske einschränken. Diese Einschränkung wird erst von FindFirst/FindNext nachgerüstet, indem die nicht passenden Einträge übersprungen werden.

himitsu 8. Mär 2007 12:31

Re: Findfirst...Findnext funktioniert nicht 100%ig
 
Zitat:

Zitat von jbg
Übrigens, die FindFirstFile/FindNextFile API Funktionen, die von FindFirst/FindNext aufgerufen werden liefern immer alle Dateien. Da kann man nicht auf eine Dateimaske einschränken. Diese Einschränkung wird erst von FindFirst/FindNext nachgerüstet, indem die nicht passenden Einträge übersprungen werden.

Wie kommst du auf diese Idee?

Ich nutze diese WinAPI schon lange MSDN-Library durchsuchenFindFirstFile und kann dir das Gegenteil bestätigen.

und hier mal der Beweis aus'm MSDN

Zitat:

lpFileName:
A pointer to a null-terminated string that specifies a valid directory or path, and file name that can contain wildcard characters, for example, an asterisk (*) or a question mark (?).
...

Vielleicht solltest du dir nochmals die Quellen von FindFirst/FindNext in deinem Delphi genauer ansehn, also was diese wirklich machen. ;)

SirThornberry 8. Mär 2007 12:39

Re: Findfirst...Findnext funktioniert nicht 100%ig
 
da muss ich himitsu zustimmen. Wenn man den Quelltext anschaut sieht man das auch an die Apifunktion eine maske übergeben wird.
Im übrigen sollte man nicht "*.*" als Maske verwenden sondern "*". Schließlich will man alle Dateinamen und nicht nur die wo ein "." drin vorkommt. Zwar wird bei "*.*" auch alles ohne punkt gefunden aber wer weiß wann dieser Bug behoben wird.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:23 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz