Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Rekursive Dateisuche mit globale Variable abbrechen


galagher - Mo 15.12.08 20:47
Titel: Rekursive Dateisuche mit globale Variable abbrechen
Hallo!

Der folgende Code sucht in "Path" nach "Mask" Dateien, Mask kann mehrere Dateinamenerweiterungen enthalten, zB.
FindFile('C:\', '*.exe,*.txt,*.pdf', Memo1.Lines, True, Label1, Label2);
Es ist also eine rekursive Dateisuche, und es können mehrere Dateitypen angegeben werden. Man kann jederzeit abbrechen, wenn man die bool'sche Variable bStop auf True setzt. Wenn diese Prozedur innerhalb der aufrufenden Unit steht, sieht das so aus - beachte die Stellen mit //**:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
procedure TForm1.FindFile(Path, Mask: String; List: TStrings;
  SubFolder: Boolean; CountLabel, FNameLabel: TLabel);
var
  Attr, k: Integer;
  Search: TSearchRec;
begin
  Attr := faAnyfile and not faDirectory;

  Path := IncludeTrailingPathDelimiter(Path);

  with TStringList.Create do
  try
    CommaText := Mask;

    for k := 0 to Count - 1 do
    if FindFirst(Path + Strings[k], Attr, Search) = 0 then
      repeat
       List.Add(Path + Search.Name);

       //**
       Application.ProcessMessages;
       if bStop then
       begin
        SysUtils.FindClose(Search);
        break;
       end;
       //**

      until FindNext(Search) <> 0;

   SysUtils.FindClose(Search);
  finally Free end;

  {Dateien zählen}
  if not (CountLabel = nilthen
  begin
   CountLabel.Caption := IntToStr(List.Count);
   CountLabel.Update;
  end;
  {Pfad+Dateinamen anzeigen}
  if not (FNameLabel = nilthen
  begin
   FNameLabel.Caption := Path + Search.Name;
   FNameLabel.Update;
  end;

  if SubFolder then
  begin
    if FindFirst(Path + '*.*', faDirectory, Search) = 0 then
    begin
      repeat
        if ((Search.Attr and faDirectory) = faDirectory) and
          (Search.Name[1] <> '.'then
          FindFile(Path + Search.Name, Mask, List, SubFolder, CountLabel, FNameLabel);

          //**
          Application.ProcessMessages;
          if bStop then
          begin
           SysUtils.FindClose(Search);
           break;
          end;
          //**

      until FindNext(Search) <> 0;

      SysUtils.FindClose(Search);
    end;
  end;
end;


Wie muss der Code aussehen, wenn er in einer anderen Unit steht?
Ich möchte dabei immer noch abbrechen können, aber wie übergebe ich so etwas wie bStop?


Moderiert von user profile iconNarses: Topic aus Dateizugriff verschoben am Mo 15.12.2008 um 19:53


Xentar - Mo 15.12.08 20:53

Öhm.. genauso?
Als Parameter reinreichen geht ja nicht, also muss es eine (globale) Variable sein, wo die Prozedur Zugriff drauf hat.


Narses - Mo 15.12.08 20:54

Moin!

Einfach als Referenz-Parameter übergeben:

Delphi-Quelltext
1:
2:
procedure TForm1.FindFile(Path, Mask: String; List: TStrings;
  SubFolder: Boolean; CountLabel, FNameLabel: TLabel; var bStop: Boolean);
Wird der Wert ausserhalb der Funktion verändert (in einer von APM aufgerufenen Methode), wirkt sich das natürlich auch auf einen Referenz-Parameter aus. :idea:

cu
Narses

//EDIT: Der Titel des Threads ist nicht soo glücklich gewählt, es geht ja nicht um die Dateisuche (das könnte ja auch alles andere sein), sondern darum, eine globale Variable in einer (rekursiven) Prozedur zu ersetzen. Kannst du das bitte noch etwas anpassen? Danke. :)


galagher - Mo 15.12.08 22:02

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Einfach als Referenz-Parameter übergeben:

Danke - klappt perfekt!

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
//EDIT: Der Titel des Threads ist nicht soo glücklich gewählt, es geht ja nicht um die Dateisuche (das könnte ja auch alles andere sein), sondern darum, eine globale Variable in einer (rekursiven) Prozedur zu ersetzen. Kannst du das bitte noch etwas anpassen? Danke. :)

Das könnte ich nur, wenn ich vor dem Erstellen des Threads gewusst hätte, dass es um eine globale Variable in einer (rekursiven) Prozedur geht, wobei ich dann aber den Thread nicht hätte erstellen müssen, weil ich die Lösung ja gekannt hätte!


Narses - Mo 15.12.08 22:14

Moin!

user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:
Danke - klappt perfekt!
Fein, bitte. ;)

user profile icongalagher hat folgendes geschrieben Zum zitierten Posting springen:
Das könnte ich nur, wenn ich vor dem Erstellen des Threads gewusst hätte, dass es um eine globale Variable in einer (rekursiven) Prozedur geht, wobei ich dann aber den Thread nicht hätte erstellen müssen, weil ich die Lösung ja gekannt hätte!
Du kannst den Thread-Titel schon anpassen, solange du den ersten Beitrag editieren darfst. :zwinker: Es geht ja auch darum, dass jemand, der nun zufällig nicht eine rekursive Dateisuche abbrechen möchte, sondern eben eine globale Variable ersetzen will, von diesem Thread-Titel sicher nicht den passenden Inhalt erwarten würde. :idea: Also: Bitte wähle (auch gerade jetzt nachträglich) einen passenderen Thread-Titel. :)

cu
Narses


galagher - Di 16.12.08 18:02

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Du kannst den Thread-Titel schon anpassen, solange du den ersten Beitrag editieren darfst. :zwinker:

Gut, überredet! :mrgreen: