Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Aktuelle Datei finden (https://www.delphipraxis.net/216317-aktuelle-datei-finden.html)

Willie1 9. Dez 2024 17:52

Aktuelle Datei finden
 
Hallo Leute,
ich habe eine große Zahl von Dateien mit den Namen: 1-Liga00.fus, ... 2-Liga25, 3-Liga25.fus usw., wobei die Zahl das Jahr angibt. Das Jahr 3??? interessiert hier nicht. Ich will jetzt nur die aktuellen Dateien auswählen können. Der Dateiname wird bei der Anlage so festgelegt.
Ich habe mir Folgendes gedacht:
Delphi-Quellcode:
function FindFootballFiles(const Path: string): TStringDynArray;
var
  FileFilter : TDirectory.TFilterPredicate;
  s: string;
  J, Lj: Word;
  Po: Integer;
begin
  FileFilter :=
    function(const Path: String; const SearchRec: TSearchRec): Boolean
    begin
      po := Pos('.',SearchRec.Name)-3;
      s := string(SearchRec.Name).SubString(Po,2);
      try
        Lj := s.ToInteger + 2000;
      except
        Exit(false);
      end;
      J := YearOf(Today);
      Result := (J = Lj) or (J = Pred(Lj));
    end;
    Result := TDirectory.GetFiles(Path, '*.fus', TSearchOption.soAllDirectories, FileFilter);
end;
Wie findet ihr diesen Ansatz? Ist mir klar, wenn der Anwender den Dateinamen ändert, funktioniert die Sache nicht mehr.
Gruß Willie.

ringli 9. Dez 2024 18:33

AW: Aktuelle Datei finden
 
Ich bin mir nicht sicher ob ich dich richtig verstehe, aber versuch es mal so:
Delphi-Quellcode:
function FindFootballFiles(const Path: string): TStringDynArray;
var
  FileFilter : TDirectory.TFilterPredicate;
begin
  var sYear : string := FormatDateTime('YY', Now);
  SearchPattern := Format('?-Liga%s.fus', [sYear]);

  FileFilter :=
    function(const Path: String; const SearchRec: TSearchRec): Boolean
    begin
      Result := Winapi.ShLwApi.PathMatchSpecW(PChar(SearchRec.Name), PChar(SearchPattern));
    end;
 
  Result := TDirectory.GetFiles(Path, '*.*', TSearchOption.soAllDirectories, FileFilter);
end;

himitsu 9. Dez 2024 19:14

AW: Aktuelle Datei finden
 
Debuggen ist wohl etwas, was du nie benutzt?

Zitat:

Delphi-Quellcode:
try
  StrToInt oder .ToInteger
except
  // nix machen
end;

Für sowas sollte einem der Popo verhauen werden.

Delphi-Referenz durchsuchenTryStrToInt oder Delphi-Referenz durchsuchenStrToIntDef


Delphi-Quellcode:
if TryStrToInt(RightStr(ChangeFileExt(SearchRec.Name, ''), 2), i) then
  MachWasMit(i);

FriedrichAT 9. Dez 2024 19:45

AW: Aktuelle Datei finden
 
Hallo
Ich machs "meisten" so...

Delphi-Quellcode:
// Liest das Übergebene "Dir" ein
procedure TForm1.ReadDir(const Dir: String);
var ExtMask: TDirectory.TFilterPredicate;
    SOpt: TSearchOption;
begin
  // ----------------------------------------------------------------------
  ExtMask:= function(const Pfad: String; const SR: TSearchRec): Boolean
            begin
              Result:= (ExtractFileExt(SR.Name) = '.fus');
            end;
  // ----------------------------------------------------------------------
  if CbRecursive.Checked then                            // Ist ein CheckBox
    SOpt:= TSearchOption.soAllDirectories
  else
    SOpt:= TSearchOption.soTopDirectoryOnly;

  FArr:= TDirectory.GetFiles(Dir, '*.*', SOpt, ExtMask); // Ist dein TStringDynArray
end;

himitsu 9. Dez 2024 20:52

AW: Aktuelle Datei finden
 
Zitat:

Ich machs "meisten" so...
abc.FUS ?

SameText/
Zitat:

AnsiSameText
oder Delphi-Referenz durchsuchenSameFileName

Und wenn du eh nur nach der Dateiendung filtern willst, ist das eh unnötig zuviel.
Delphi-Quellcode:
TDirectory.GetFiles(Dir, '*.fus', SOpt)



Und da wir schon dabei sind, gibt es eine geheime Funktion, in der Delphiklasse, denn sie lässt nicht Windows (Bei Google suchenFindFirstFile) filtern, sondern macht das selbst Delphi-Referenz durchsuchenMatchesMask und das kennt auch Char-Sets/Ranges. (und nein, es ist kein RegEx!!!)
Delphi-Quellcode:
var
  Year, i: Integer;
  Found: string;
begin
  Year := -1;
  Found := '';
  for var Filename in TDirectory.GetFiles('C:\_D', '*[0-9][0-9].fus', TSearchOption.soAllDirectories) do
    if TryStrToInt(RightStr(ChangeFileExt(Filename, ''), 2), i) and (i > Year) then begin
      Year := i;
      Found := Filename;
    end;
  ShowMessage(i.ToString + ' ' + Found);
end;

Willie1 11. Dez 2024 18:40

AW: Aktuelle Datei finden
 
Zitat:

Zitat von himitsu
Delphi-Quellcode:
if TryStrToInt(RightStr(ChangeFileExt(Filename, ''), 2), i) and (i > Year) then

Dann muss aber der Compiler auf Kurzschluss gestellt sein. Was enthält i, wenn Try fehlschlägt? Was aber eigentlich nicht passieren kann wg. der Suchmaske.

Dann noch etwas Grundsätzliches: Ich könnte natürlich eine Recent-Liste anlegen. Aber die zeigt stur immer die zuletzt aufgerufenen Dateien an, während meine Lösung die aktuellen Files zur Auswahl anbietet! Oder Beides?

Himitsu, ich habe mal nach deinem Nicknamen gegooglet, interessant. Du hast die besten Tricks drauf. So werde ich es machen.

Willie.

himitsu 11. Dez 2024 19:18

AW: Aktuelle Datei finden
 
Wenn möglich, versuch ich schon das vom Delphi selbst zu nutzen.
Ist nicht immer das Idealste, aber z.B. die IOUtils sind einfacher und dadurch fehlerunanfälliger und erzeugen auch so "übersichtlicheren" Code, gegenüber den alten Pascal-Prozeduren oder der WinAPI, vor allem wenn es auch noch rekursiv oder iterativ wird.

Zitat:

Zitat von Willie1 (Beitrag 1544111)
Dann muss aber der Compiler auf Kurzschluss gestellt sein.

Was aber auch der Standard ist und IMHO besser auch sein sollte.

Wobei es hier jetzt auch nicht schlimm wäre, jedenfalls im Endergebnis. (und bei dem zweiten Vergleich würde es nicht stören, wenn i auf einem Zufallswert läge)

PS: PostgreSQL hatte mal die volle Auswertung im PLSQL, aber sie haben eingesehn, dass es voll beschissen ist.

Es ist auch meistens einer der Fälle, wo ich dieses Compilersetting nicht explizit vorgebe und auch nicht drauf prüfe, falls es wer umstellt ... isser halt selbst Schuld :oops: (andere Settings prüfe ich entweder oder gebe sie für meine Funktion/Unit vor)



Man muß nichtmal das Result-Array der Funktion benutzen. (einfach immer blind False zurückgeben, damit das Array nicht sinnlos gefüllt wird)
In der Methode kannst du das Gewünschte ja so benutzen und dort auch extern speichern, wie und wo auch immer du willst. (oder Beides gemeinsam nutzen)

Für ein Projekt hatte ich zuletzt GetFiles nur benutzt um "alle" Dateien zu suchen
und dann nachher auf dieses Array gefiltert, für unterschiedliche Dateien und Vorgänge,
also einmal suchen und dann "schnell" das Array (als Cache), anstatt für Jeden einzeln.

So könnte man auch das noch gemütlich z.B. mit einer RecentListe kombinieren. :)




In diesem Fall war es einfacher die Vergleichmethode sich zu sparen.
Das RESULT vorher in eine Variable und man kann beim Anzeigen einen Fortschritt anzeigen (exklusive der Zeit für die Suche selbst).

Direkt in der Vergleichsmethode arbeiten, könnte man beim Suchen die Position (Pfad) als Fortschritt anzeigen (weiß aber natürlich die Anzahl nicht).

Doppelt suchen hatte ich früher mal gemacht, aber es ist immer langsamer.
Na gut, beim Suchen den Suchfortschritt (wenn man viele Dateien/Verzeichnisse sucht)
und am Ende dann nochmal über das Array und dort kann man dann den Gesamtfortschritt + Restzeit ausgeben, wenn die Verarbeitung "langsamer" ist.

Willie1 12. Dez 2024 16:33

AW: Aktuelle Datei finden
 
Zitat:

Was aber auch der Standard ist und IMHO besser auch sein sollte.
Stimmt. Ich hab' vor Jahren mal einen Programmierkurs für Pascal besucht. Der Dozent hatte den Spruch drauf "man solle sich nicht auf den Zufall verlassen, das könne schief gehen". Irgendwann in ferner Zukunft hat i den Wert z.B. 55 und dann würde die Funktion crashen. Aber durch die Suchmaske *[0-9][0-9].fus kann das eigentlich nicht passieren.:)


Ich werde versuchen, Recentliste und die aktuellsten Files in eine Liste zusammen zu bringen. Also an die Arbeit!

himitsu 12. Dez 2024 17:01

AW: Aktuelle Datei finden
 
In aktuellen Delphis kann man ja nun wunderschön mit Arrays rechnen ... so als wären es Strings. (drum wurden diese Features damals auch mit "new string-like array operations" extrem enthusiastisch vorgestellt)

Delphi-Quellcode:
var Files :=
    TDirectory.GetFiles(Dir, '*.fus')
  + TDirectory.GetFiles(Dir, '*.blubb')
  + TDirectory.GetFiles(Dir, '*.holladiewaldfee');
TArray.Sort<string>(Files);
ShowMessage(string.Join(sLineBreak, Files));
Delphi-Quellcode:
var arr: TArray<string>; // oder TStringDynArray oder array of string oder ...

arr := ['abc', '123', 'xyz'];

s  := 'def';
arr := arr + [s];

arr := arr + arr;

TArray.Sort<string>(arr);
if TArray.BinarySearch<string>(arr, 'xyz', i) then
  ShowMessage(i.ToString);

if TArray.Contains<string>(arr, 'abc') then

var i := TArray.IndexOf<string>(arr, 'def');
Sowie Insert und Delete können endlich auch für Arrays benutzt werden.

Willie1 13. Dez 2024 19:06

AW: Aktuelle Datei finden
 
Muss ich ausprobieren! Die Suche nach der richtigen Datei muss schnell gehn. Wi.


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