Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Dateien Rekursiv suchen -- Klappt nicht ganz (https://www.delphipraxis.net/5902-dateien-rekursiv-suchen-klappt-nicht-ganz.html)

mirage228 22. Jun 2003 17:50


Dateien Rekursiv suchen -- Klappt nicht ganz
 
Hallo,

ich habe in der CodeLib hier bereits einen Beitrag gefunden, mit dem Dateien in einem Verzeichnis (inkl. Unterverzeichnisse) suchen kann.
Jedoch hatte diese Funktion einen Haken. Wenn im ersten angegebenen Pfad keine entsprechende Datei war, sprang die Procedure sofort raus.

Ich habe das ganze daher ein wenig um gebastelt.
Nun habe ich aber das Problem, dass manchmal eine AccessViolation (in ntdll.dll) auftritt!

Delphi-Quellcode:
procedure TSearchFiles.FindFile(RootFolder, Mask: String; SaveTo: TStringList; FoundFirst: Boolean);
var
  SR,SR2: TSearchRec;
begin
  if AnsiLastChar(RootFolder)^ <> '\' then
    RootFolder := RootFolder + '\';
  if Mask = '' then
    Mask := '*.*';
  if FindFirst(RootFolder + '*.*', faAnyFile, SR) = 0 then
  try
    repeat
    if SR.Attr and faDirectory = faDirectory then
    begin
      if (SR.Name <> '.') and (SR.Name <> '..') then
        FindFile(RootFolder + SR.Name, Mask, SaveTo, FoundFirst); // <-- AccessViolation hier nach ner Zeit
    end else
    if not FoundFirst then
    begin
      if FindFirst(RootFolder + Mask, faAnyFile, SR2) = 0 then
      begin
        SaveTo.Add(RootFolder + SR2.Name);
        FoundFirst := True;
      end;
    end else
    begin
      if FindNext(SR2) = 0 then
      SaveTo.Add(RootFolder + SR2.Name);
    end;
    until (FindNext(SR) <> 0);
  finally
    FindClose(SR);
    FindClose(SR2);
  end;
end;
Woran liegts??

mfg
mirage228

Daniel B 22. Jun 2003 17:56

Re: Dateien Rekursiv suchen -- Klappt nicht ganz
 
Hallo,
Zitat:

Zitat von mirage228
Nun habe ich aber das Problem, dass manchmal eine AccessViolation (in ntdll.dll) auftritt!

Was bedeutet denn "manchmal"? Besteht die möglichkeit des Debuggens?

Grüsse, Daniel :hi:

mirage228 22. Jun 2003 18:00

also z.b.

ich hab das verz:

D:\Eigene Dateien

ich suche nach *.mp3, diese sind in D:\Eigene Dateien\Eigene Musik

die findet er alle!, aber...

wenn ich als verzeichnis z.b. D:\Eigene Dateien (wo die *.doc drinne sind) angebe und als Filter *.doc, dann kommt der Fehler an der besagten stelle..........

arnoldo 22. Jun 2003 19:36

Hallo Mirage228,

einen Fehler konnte ich bei Dir nicht gleich entdecken,
jedoch habe ich schon einmal so etwas programmiert.
Mit den folgenden Code-Zeilen müsste es funktionieren.

Delphi-Quellcode:
procedure filelist(path:string);
var f,f2:tsearchrec;
begin
 if findfirst(path+'*.*',faAnyFile,f)=0 then
  begin

   if findfirst(path+'*.htm',faAnyFile,f2)=0 then {falls *.htm Dateien gefunden}
    begin
      form1.ListBox1.Items.Add(path+f2.Name); {ab in die Listbox}
      while findnext(f2)=0 do form1.ListBox1.Items.Add(path+f2.Name);
    end;


    while findnext(f)=0 do {Verzeichniserkennung}
     if ((f.Attr and faDirectory)>0) and (f.name[1]<>'.') then
        filelist(path+f.Name+'\'); {in die nächste Verzeichnisebene}

  end;
 FindClose(f);
end;

mirage228 22. Jun 2003 20:02

Danke sehr, funktioniert super!

:dancer: :dancer2: :spin:

mfG
mirage228

Christian Seehase 23. Jun 2003 11:41

Moin Arnoldo,

mal wieder einer der beliebtesten Fehler ;-)

Diese Abfrage ist leider falsch

Delphi-Quellcode:
(f.name[1]<>'.')
es muss heissen

Delphi-Quellcode:
(f.name <> '.') and (f.name <> '..')
in den meisten Fällen wird der Fehler zwar nicht auffallen, aber Datei und Verzeichnisnamen dürfen unter Windows durchaus mit einem . beginnen, auch wenn man dies mit dem Explorer nicht hinbekommt. (aus der Konsole heraus geht es z.B.)

arnoldo 23. Jun 2003 22:43

Danke für den Tipp, das ist mir noch gar nicht aufgefallen. :idea:
Werde das gleich mal korrigieren:

Delphi-Quellcode:
 *if ((f.Attr and faDirectory)>0) and
      (f.name<>'.') and (f.name<>'..') then
     filelist(path+f.Name+'\');

negaH 27. Jun 2003 12:11

(f.Attr and faDirectory)>0

ist ebenfalls "falsch", bzw. unsicher.
Du kombinierst einen Boolschen Operator -> and, mit einem Integer Vergleich > 0. Bei Boolschen Abfragen immer auf eine Boolsche Wahrheit testen. Also so

(F.Attr and faDirectory <> 0) oder
(F.Attr and faDirectory = 0).

Warum ? Ganz einfach (-1 and $80000000) > 0 ergibt False OBWOHL das 31.te Bit in -1 gesetzt ist. Da aber dieses Bit das Vorzeichen Bit ist muß > 0 fehlschlagen das da -1 and $8000000 = -MaxInt ist.

Dagegen ergibt (-1 and $80000000 <> 0) = TRUE.

Gruß Hagen

Christian Seehase 27. Jun 2003 12:43

Moin Hagen,

stimmt, hatte ich übersehen :oops:

In solchen Fällen benutze ich für meinen Teil auch

(F.Attr and faDirectory) = faDirectory

Damit kann man das Vorzeichenproblem auch umgehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:40 Uhr.

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