Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Probleme mit GetFilesInDirectory Procedure (https://www.delphipraxis.net/76797-probleme-mit-getfilesindirectory-procedure.html)

Dash 10. Sep 2006 01:28


Probleme mit GetFilesInDirectory Procedure
 
Hi,

ich habe mir folgenden Code aus dem Delphi Forum kopiert:

Delphi-Quellcode:
procedure GetFilesInDirectory(Directory: String; const Mask: String;
List: TStrings;
WithSubDirs, ClearList: Boolean);

procedure ScanDir(const Directory: String);
var
  SR: TSearchRec;
begin
  if FindFirst(Directory + Mask, faAnyFile - faDirectory, SR) = 0 then try
repeat
  List.Add(Directory + SR.Name)
  until FindNext(SR) <> 0;
finally
  FindClose(SR);
end;

if WithSubDirs then
  begin
    if FindFirst(Directory + '*.*', faAnyFile, SR) = 0 then
  try
    repeat
      if (SR.Attr = faDirectory) and
      (SR.Name <> '.') and (SR.Name <> '..') then
      ScanDir(Directory + SR.Name + '\');
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
  end;
end;

begin
  List.BeginUpdate;
try
  if ClearList then
  List.Clear;
  if Directory = '' then Exit;
  if Directory[Length(Directory)] <> '\' then
  Directory := Directory + '\';
  ScanDir(Directory);
  finally
    List.EndUpdate;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  GetFilesInDirectory('C:\', '*.*', Listbox1.Items, False, True);
end;

procedure TForm1.Button1Click(Sender: Tobject);
var
  F: TSearchRec;
begin
  if FindFirst(ed_dateiname.text, faAnyFile, F) = 0 then try
  Label1.Caption := F.Name
  Label2.Caption := IntToStr(F.Size);
  finally
    FindClose(F);
  end;
end;
Allerdings habe ich jetzt das Problem, dass er z.B. einfach C:\Programme auslässt wenn ich als Ordner C:\ angebe. Aber auch eine Menge anderer Ordner wie Temp Ordner werden einfach ausgelassen... kann mir jemand sagen was hier schief läuft?

Gruß
Dash

Go2EITS 10. Sep 2006 06:49

Re: Probleme mit GetFilesInDirectory Procedure
 
Ich glaube Dein False musst Du in True umbenennen, also so:
Delphi-Quellcode:
GetFilesInDirectory('C:\', '*.*', Listbox1.Items, True, True);
Grüße Go2EITS

Christian Seehase 10. Sep 2006 10:08

Re: Probleme mit GetFilesInDirectory Procedure
 
Moin Dash,

diese Zeile

Delphi-Quellcode:
if (SR.Attr = faDirectory) and
muss so

Delphi-Quellcode:
if ((SR.Attr and faDirectory) <> 0) and
aussehen.
Auch ein Directory kann mehr als ein Attribut haben, und wenn das der Fall ist, klappt der Vergleich mit = nicht mehr, um ein Verzeichnis zu erkennen.

[EDIT]
Ausserdem sollte man Bitmasken, niemals mit + und - bearbeiten

Delphi-Quellcode:
if FindFirst(Directory + Mask, faAnyFile - faDirectory, SR) = 0 then try
auch wenn das in diesem Falle sogar funktionieren würde, sollte es besser

Delphi-Quellcode:
if FindFirst(Directory + Mask, faAnyFile AND NOT faDirectory, SR) = 0 then try
heissen. Hier hat übrigens das Beispiel zu FindFirst in der Delphi-Hilfe auch einen Fehler, da hier die Attribute mit + verknüpft werden (richtig wäre OR).
Hier hatte ich das schon einmal ausführlich erklärt.


Da FindFirst sich so gut wie nicht um den übergebenen Attributwert kümmert, wäre es sicherer es so zu schreiben:

Delphi-Quellcode:
  if FindFirst(Directory + Mask, faAnyFile, SR) = 0 then try
repeat
  if (sr.Attr and faDirectory) = 0 then List.Add(Directory + SR.Name)
  until FindNext(SR) <> 0;
[/EDIT]

Dash 10. Sep 2006 19:47

Re: Probleme mit GetFilesInDirectory Procedure
 
Zitat:

Zitat von Go2EITS
Ich glaube Dein False musst Du in True umbenennen, also so:
Delphi-Quellcode:
GetFilesInDirectory('C:\', '*.*', Listbox1.Items, True, True);
Grüße Go2EITS

Stimmt, ich hatte es bei mir aber schon geändert :wink:

@Christian
Ich habe nun deinen letzten Code benutzt, allerdings hört er nach der ersten Datei auf zu scannen :?

Gruß
Dash

Migo 14. Feb 2025 17:01

AW: Probleme mit GetFilesInDirectory Procedure
 
Liste der Anhänge anzeigen (Anzahl: 1)
Das Thema ist zwar schon einige Jahre alt... aber ich nutze die Rekursive Suche mit GetFilesInDirectory immer noch gerne:
Code:
procedure GetFilesInDirectory(Directory: string; const Mask: string; List: TStrings; WithSubDirs, ClearList: Boolean);

  procedure ScanDir(const Directory: string);
  var
    SR: TSearchRec;
  begin
    if FindFirst(Directory + Mask, faAnyFile and not faDirectory, SR) = 0 then try
      repeat
        List.Add(Directory + SR.Name)
      until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;

    if WithSubDirs then begin
      if FindFirst(Directory + '*.*', faAnyFile, SR) = 0 then try
        repeat
          if ((SR.attr and faDirectory) = faDirectory) and
             (SR.Name <> '.') and (SR.Name <> '..') then
            ScanDir(Directory + SR.Name + '\');
        until FindNext(SR) <> 0;
      finally
        FindClose(SR);
      end;
    end;
  end;

begin
  List.BeginUpdate;
  try
    if ClearList then List.Clear;
    if Directory = '\' then Exit;
    if Directory[Length(Directory)] <> '\' then
      Directory := Directory + '\';
    ScanDir(Directory);
  finally
    List.EndUpdate;
  end;
end;
Nun ist aber mein ungelöstes Problem, das ich bei der Suche in C:\ProgramData folgendes als Ergebnis bekomme, wenn ich nach "lights*" suche: Siehe angehängten Screenshot.

?!? Er dürfte mir die Dateien "Light Skin..." doch gar nicht anzeigen? Was mag der Grund sein?

Gruß,
Migo

himitsu 14. Feb 2025 17:53

AW: Probleme mit GetFilesInDirectory Procedure
 
Altes ANSI-Delphi? (D7 oder davor)
Und kein Kompatibilitätsmanifest vorhanden, bzw. läuft die Anwendung in einem Kompatibilitätsmodus? (WinXP oder so)


Hmmm, eigentlich sieht es nicht so aus,
aber würden die ShortNames verwendet, dann wäre es eine Erklärung. :gruebel:

Ohh ja, es werden ShortName und LongName vom FindFirst/FindNext berücksichtigt.

Verwende deinen Debugger und schau, was im SR alles drin steht, bzw. genauer in SR.FindData.cAlternateFileName :angle:




Ist Directory leer
Delphi-Quellcode:
''
, dann raucht es dir ab
Delphi-Quellcode:
if Directory[Length(Directory)] <> '\' then
      Directory := Directory + '\';
und, selbst wenn nicht, dann sollte
Delphi-Quellcode:
if Directory = '\' then Exit;
bestimmt erst danach erfolgen.

Delphi-Referenz durchsuchenEndsStr, bzw. IncludeTrailingBackslash Delphi-Referenz durchsuchenIncludeTrailingPathDelimiter

Delphi-Referenz durchsuchenTDirectory.GetFiles

Migo 15. Feb 2025 09:26

AW: Probleme mit GetFilesInDirectory Procedure
 
Zitat:

Zitat von himitsu (Beitrag 1546229)
Ohh ja, es werden ShortName und LongName vom FindFirst/FindNext berücksichtigt.

Danke Dir für Dein Feedback.
Ja, es werden beide wohl berücksichtigt - leider fehlt mir aktuell das Wissen, meine Prozedur so umzubauen, dass nur LongNames berücksichtigt werden. :cry:

himitsu 15. Feb 2025 09:59

AW: Probleme mit GetFilesInDirectory Procedure
 
Den Namen nochmals mit Delphi-Referenz durchsuchenMatchesMask (System.Masks) prüfen.

Ob jetzt FindFirst oder via Delphi-Referenz durchsuchenTDirectrory.GetFiles, ist dabei auch egal.

Delphi.Narium 15. Feb 2025 10:05

AW: Probleme mit GetFilesInDirectory Procedure
 
TSearchRec hat auch noch das Feld FindData. Da gibt es dann SearchRec.FindData.cFileName für den langen Dateinamen und SearchRec.FindData.cAlternateFileName für den kurzen Dateinamen.

Wenn Du nun nach lights* suchst, prüfst Du in cFileName, ob's auch mit lights beginnt. Light Skin fiele dann raus.

Wenn Du willst kannst Du die Prüfung dann auch noch casesensitiv machen, damit sich lights und Lights auch noch unterscheiden lassen.

Ansonsten: Reguläre Ausdrücke oder MatchesMask (wie schon vorgeschlagen).

Migo 15. Feb 2025 13:51

AW: Probleme mit GetFilesInDirectory Procedure
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1546249)
Ansonsten: Reguläre Ausdrücke oder MatchesMask (wie schon vorgeschlagen).

Ganz lieben Dank Euch beiden! Ihr habt mir sehr geholfen mit Eurer Hilfestellung.

Ich konnte mir mit
Code:
if MatchesMask(SR.Name, Suchmaske) then
nun weiterhelfen und bekomme jetzt die richtigen Ergebnisse angezeigt.


Interessanterweise konnte mir die Abfrage mit
Code:
if MatchesMask(SR.FindData.cFileName, Suchmaske) then
da nicht weiterhelfen. Sie zeigte nicht das gewünschte Ergebnis an.


:-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:15 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