Entwickler-Ecke

Dateizugriff - FindFirst / FindNext findet zu viele Dateien


UweK - Di 17.05.22 11:28
Titel: FindFirst / FindNext findet zu viele Dateien
Hallo,

Diese simple kleine Funktion stellt mir eine Liste der zu einem Namensschema passenden Dateien in einem Verzeichnis zusammen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
function GetExistingFileNames(ADirectory, AFileNameTemplate: String; AFileNamesFound: TStringList): Integer;
var
  SearchRecord: TSearchRec;
  FullPath: String;
  SearchResult: Integer;
begin
  FullPath:= IncludeTrailingPathDelimiter(ADirectory) + AFileNameTemplate;

{Liste der Dateinamen zusammenstellen. Sie muss bereits vorher mit "TStringList.Create" erzeugt worden sein.}
  SearchResult:= FindFirst(FullPath, faNormal, SearchRecord);
  try
    while (SearchResult = 0do
      AFileNamesFound.Add(SearchRecord.Name);
      SearchResult:= FindNext(SearchRecord);
    end;
  finally
    FindClose(SearchRecord);
    Result:= AFileNamesFound.Count;
  end;
end;


Mein Problem ist nun, dass für die Extension des angegebenen AFileNameTemplate nicht nur dieser String akzeptiert wird, sondern auch alle längenen Extensions, die mit diesem String beginnen. Beispiel: "AFileNameTemplate = '*.txt' => wird als '*.txt*' interpretiert, d.h. es kommt auch '*.txt_backup' durch. Meine erste Idee war, noch einmal von Hand zu prüfen, ob die Extension in AFileNameTemplate wirklich genau gleich der Extension einer gefundenen Datei ist. Aber das funktioniert nur, wenn die Extension explizit angegeben wird. Es funktioniert nicht mehr, wenn z.B. "AFileNameTemplate = '*.*'" oder "AFileNameTemplate = '*.t*" übergeben wird, weil dann natürlich der '*' nicht als allgemeines Auslassungszeichen, sondern als dieses spezielle Zeichen behandelt wird. '*.*' findet dann gar nichts mehr.

Hat jemand einen Tipp für mich? Vielen Dank und Gruß von Uwe


Th69 - Di 17.05.22 15:09

Hallo,

das kann ich nachvollziehen. Ich habe unter File-Routines [https://www.onlinedelphitraining.com/delphi-file-routines] das Beispielprojekt (ganz unten) heruntergeladen und bei mir ausgeführt ("Find") und erhalte bei "*.txt" sowohl die ".txt"-Dateien als auch ".txt_backup" sowie alle anderen mit längerer ".txt"-Extension.
Die Suche nach "*.tx" liefert jedoch dann keine Ergebnisse.

Da FindFirst intern auch nur die WinAPI-Funktion FindFirstFile [https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfilea] aufruft, liegt die Antwort (der Fehler?) wohl dort. Ich erhalte dasselbe Ergebnis auch bei Verwendung von "dir" in der Eingabeaufforderung (Windows-Konsole).

Ist wahrscheinlich bedingt durch die ehemalige 8.3 Dateinamenbegrenzung.

Als Lösung fällt mir nur ein die "Extension" als Parameter getrennt zu übergeben und, wie du geschrieben hast, selber zu überprüfen.
Oder mal den Code aus dem Anhang überprüfen (den ich irgendwoher aus den Tiefen des Internets habe)...


UweK - Fr 20.05.22 11:52

Hallo,

Danke fürs Probieren. Wenn ich die Extensions der von "FindFirst/FindNext" gelieferten Dateien noch einmal mit der Delphifunktion "MatchesMask" nachprüfe, funktioniert es nun wie beabsichtigt.

Gruß Uwe


jaenicke - Fr 20.05.22 17:03

Es gibt dafür eine Einstellung: Win95TruncatedExtensions [https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc756733(v=ws.10)]
Diese dürfte nicht nur für die Kommandozeile, sondern auch für diese Befehle gelten. Getestet habe ich das nicht.

Hintergrund ist, dass intern die Kommandozeile und ältere API-Befehle die 8.3 Schreibweise der Dateinamen verwenden, wobei die Dateierweiterung auf 3 Zeichen verkürzt wird. Der Rest der Erweiterung wird daher ignoriert.

Moderiert von user profile iconTh69: URL-Titel hinzugefügt.


Sinspin - Mo 23.05.22 18:45

Generell verwende ich FindFirst / FindNext immer mit *.* und faAnyFile.
Und untersuche dann die Ergebnisse mit Dateinamenzerpflücken und Dateiattribut überprüfen weiter.
Es gab in der Vergangenheit (je nach Pascal oder Delphi Version) zu oft Probleme mit den gelieferten Ergebnissen, als das ich mich auf FindFirst / FindNext noch verlassen wollen würde.


jaenicke - Mo 23.05.22 22:24

user profile iconSinspin hat folgendes geschrieben Zum zitierten Posting springen:
Es gab in der Vergangenheit (je nach Pascal oder Delphi Version) zu oft Probleme mit den gelieferten Ergebnissen, als das ich mich auf FindFirst / FindNext noch verlassen wollen würde.
Da das ja nur Wrapper um die entsprechenden API-Funktionen sind, ist die Frage, ob daran die Delphi-Version schuld war. Abgesehen von einem Problem mit dem Dateidatum hatte ich mit den Funktionen nie Probleme (und ich habe diese relativ oft benötigt).