Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Files suchen und sortieren (https://www.delphipraxis.net/161603-files-suchen-und-sortieren.html)

stahli 11. Jul 2011 22:30

Files suchen und sortieren
 
Ich ermittle einige PDF-Dateien und sortiere die nach dem Erstellungsdatum.
Das funktioniert, ich bin aber nicht sicher, ob ich die einfachste Lösung habe.
Würde es jemand anders machen?

Muss nicht mit Generics sein. Würde eine anonyme Methode etwas vereinfachen?

Delphi-Quellcode:
type

  TsrComparer = class(TComparer<TSearchRec>)
    function Compare(const sr1, sr2: TSearchRec): Integer; override;
  end;

implementation

{ TMeleePairComparer }

function TsrComparer.Compare(const sr1, sr2: TSearchRec): Integer;
begin
  Result := 0;
  if Result = 0 then
    Result := -CompareValue(sr1.TimeStamp, sr2.TimeStamp);
  if Result = 0 then
    Result := CompareStr(sr1.Name, sr2.Name);
end;

...

procedure TFormOlympic.TabSheetReportShow(Sender: TObject);

  procedure GetFiles;
  var
    sr: TSearchRec;
    srList: TList<TSearchRec>;
    F: Boolean; // ergänzt
  begin
    srList := TList<TSearchRec>.Create(TsrComparer.Create);
    if PathReport <> '' then
    begin
      F := FindFirst(PathReport + '*.pdf', (faAnyFile and not faDirectory), sr);
      while F = 0 do
      begin
        if ExtractFileExt(sr.Name) = '.pdf' then
          srList.Add(sr);
        F := FindNext(sr);
      end;
      FindClose(sr);
    end;
    srList.Sort;
    ListBoxReport.Clear;
    for sr in srList do
      ListBoxReport.Items.Add(sr.Name);
    FreeAndNil(srList);
  end;

begin
  GetFiles;
  ListBoxReport.ItemIndex := 0;
  ListBoxReportClick(Sender);
end;

PS: Auf ein TsShellListView (AlphaControls) hatte ich verzichtet, da ein umsortieren dort nicht möglich war.

daywalker9 11. Jul 2011 22:37

AW: Files suchen und sortieren
 
Könnte man auch so machen:

Delphi-Quellcode:

    lst:=TList<TSearchRec>.create;
    lst.Sort(TComparer<TSearchRec>.Construct(function (const sr1,sr2 : TSearchRec):integer
                                               begin
                                                Result := 0;
                                                if Result = 0 then
                                                  Result := -CompareValue(sr1.TimeStamp, sr2.TimeStamp);
                                                if Result = 0 then
                                                  Result := CompareStr(sr1.Name, sr2.Name);
                                               end));

himitsu 12. Jul 2011 03:17

AW: Files suchen und sortieren
 
Resourcenscchutz?

FreeAndNil ist, bei Variablen, welche eh nicht geprüft werden und nur lokal genutzt werden, etwas übertrieben.

Wieso ist das lokale
Delphi-Quellcode:
F
global deklariert, bzw. wo wurde es eigentlich deklariert?

Und jupp, an die anonymen Methoden gewöhne ich mich auch so langsam, aber ob es hier wirklich sinnvoll/nötig ist, ist eine andere Frage :D
(aber oftmals machen sie den Code schon lesbarer, da der Code dann zwar nicht wiederverwendbar ist, aber wenigenstens, bei linearen Funktionen, im Kontext des aufrufenden Codes bleibt und man nicht erst suchen/umblättern muß ... z.B. bei Synchronize-Aufrufen ist das eine geile Angelegenheite und auch kleinere Thread-Prozeduren erstelle ich heutzutage anonym :angle: )

Da man FindClose eh nur aufrufen muß, wenn FindFirst erfolgreich war, ist die Repeat-Schleife (aus dem OH-Beispiel) keine schlechte Idee.

Zitat:

Delphi-Quellcode:
ExtractFileExt(sr.Name) = '.pdf'

irgendwas.PDF oder x.PdF willst du nicht finden?

Delphi-Quellcode:
procedure GetFiles;
var
  sr: TSearchRec;
  srList: TList<TSearchRec>;
begin
  srList := TList<TSearchRec>.Create(function(const sr1, sr2: TSearchRec): Integer
    begin
      Result := 0;
      if Result = 0 then
        Result := -CompareValue(sr1.TimeStamp, sr2.TimeStamp);
      if Result = 0 then
        Result := CompareStr(sr1.Name, sr2.Name);
    end));
  try
    if (PathReport <> '') and (FindFirst(PathReport + '*.pdf', (faAnyFile and not faDirectory), sr) = 0) then
    begin
      repeat
        //if SameText(ExtractFileExt(sr.Name), '.pdf') then
        if EndsText('.pdf', sr.Name) then //Unit StrUtils
          srList.Add(sr);
      until FindNext(sr) <> 0;
      FindClose(sr);
    end;
    srList.Sort;
    ListBoxReport.Clear;
    for sr in srList do
      ListBoxReport.Items.Add(sr.Name);
  finally
    srList.Free;
  end;
end;
PS: Leider hat man in TDirectory.GetFiles (Unit IOUtils) die Sortierung vergessen, aber sonst könnte man diese neue Unit sich schonmal ansehn, auch wenn ich persönlich diese Unit für total Mißlungen halte.
Aber zumindestens die Methoden, um über nur einen Befehl auf bestimmte Dateieigenschaften zuzugreifen, ist manchmal recht praktisch.

FredlFesl 12. Jul 2011 08:58

AW: Files suchen und sortieren
 
Ich würde da noch Refacoring ansetzen:

Delphi-Quellcode:
Function FileList (aPath : String) : TSearchRecList;
Begin
  Result := TSearchRecList.Create;
  Try
    ReadDirectory (aPath, Result);
    SortListByCreationData(Result);
  Except
    Result.Free;
    Result := Nil;
    Raise;
  End;
End;
Übersichtlich, einfach zu lesen.

So praktisch Generics auch sind, so 'häßlich' finde ich sie. Ich kapsele lieber bzw. lasse sie nur in den untersten Ebenen ihr wahres Gesicht zeigen. Denn vielleicht ist eine 'TList<TSearchRec>' ja irgendwann nicht mehr das Gelbe vom Ei.

stahli 12. Jul 2011 17:51

AW: Files suchen und sortieren
 
Zitat:

Zitat von himitsu (Beitrag 1111245)
Resourcenscchutz?

Setze ich nur ein, wenn es wirklich Sinn macht.

Zitat:

Zitat von himitsu (Beitrag 1111245)
FreeAndNil ist, bei Variablen, welche eh nicht geprüft werden und nur lokal genutzt werden, etwas übertrieben.

Ist Gewohnheitssache. Free sieht so billig aus. :wink:

Zitat:

Zitat von himitsu (Beitrag 1111245)
Wieso ist das lokale
Delphi-Quellcode:
F
global deklariert, bzw. wo wurde es eigentlich deklariert?

Ups, versehentlich entfernt...

Zitat:

Zitat von himitsu (Beitrag 1111245)
Und jupp, an die anonymen Methoden gewöhne ich mich auch so langsam, aber ob es hier wirklich sinnvoll/nötig ist, ist eine andere Frage :D
(aber oftmals machen sie den Code schon lesbarer, da der Code dann zwar nicht wiederverwendbar ist, aber wenigenstens, bei linearen Funktionen, im Kontext des aufrufenden Codes bleibt und man nicht erst suchen/umblättern muß ... z.B. bei Synchronize-Aufrufen ist das eine geile Angelegenheite und auch kleinere Thread-Prozeduren erstelle ich heutzutage anonym :angle: )

Das meinte ich mit meiner Frage vor allem. Danke auch an DayWalker9.
Wobei ich mir noch nicht sicher bin, was nun wirklich übersichtlicher ist. Für meinen vorliegenden Anwendungszweck bleibe ich wohl besser bei meiner Lösung. Ich finde das dann doch etwas strukturierter. Außerdem kann man so in übersichtlicher Weise ggf. verschiedene Comparer für verschiedene Zwecke zuweisen.


Zitat:

Zitat von himitsu (Beitrag 1111245)
Delphi-Quellcode:
ExtractFileExt(sr.Name) = '.pdf'
irgendwas.PDF oder x.PdF willst du nicht finden?

Stimmt, ich bessere das nach. Aber vorliegend war es kein Problem, da die pdf´s vom Programm selbst erzeugt werden.

Danke.


EDIT: @FredFesl
Da schließe ich mich mal nicht an. Die Lösung mit den Generics ist schon ganz nett.

p80286 12. Jul 2011 18:01

AW: Files suchen und sortieren
 
Delphi-Quellcode:
Function FileList (aPath : String) : TSearchRecList;
Begin
  Result := TSearchRecList.Create;
  Try
    ReadDirectory (aPath, Result);
    SortListByCreationData(Result);
  Except
    Result.Free;
    Result := Nil;
    Raise;
  End;
End;
Ist das nicht pfui bah wegen möglicher Speicherleks?

Gruß
K-H

DeddyH 12. Jul 2011 18:16

AW: Files suchen und sortieren
 
Ich meine auch,
Delphi-Quellcode:
procedure FileList(aPath : String; DestList: TSearchRecList);
wäre besser, Beispiele hatten wir doch letztens erst.

FredlFesl 12. Jul 2011 19:50

AW: Files suchen und sortieren
 
Klar, geht auch. Hier ging es je eher um das Refactoring.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:05 Uhr.

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 by Thomas Breitkreuz