![]() |
Problem mit FindFirst und Dateiendungen
Hallo,
ich verwende folgende Procedure um die Dateinamen mit einer bestimmten Endung in einer Liste auflisten zu lassen:
Delphi-Quellcode:
Das geht auch gut - zu gut sogar!
procedure GetFilesInDirectory(Directory: String; const Mask: String; List: TStrings);
var SR: TSearchRec; begin List.BeginUpdate; try List.Clear; If Directory <> '' then begin IncludeTrailingPathDelimiter(Directory); If FindFirst(Directory + Mask, faAnyFile - faDirectory, SR) = 0 then try repeat List.Add(Directory + SR.Name) until FindNext(SR) <> 0; finally FindClose(SR); end; end; finally List.EndUpdate; end; end; Aufgerufen wird die Procedure bei mir so:
Delphi-Quellcode:
In dem Ordner "Masken_Ordner" befinden sich eben Dateien mit der Endung "*.msk*". Diese werden auch in die Liste "Masken_Dateiliste" geschrieben.
GetFilesInDirectory(Masken_Ordner, '*.msk', Masken_Dateiliste);
Wenn aber nun eine Datei die Endung "*.msk2" hat z. B. wird sie trotzdem gefunden. Wie kann ich verhindern, dass auch andere Dateien mit aufgelistet werden, sondern nur die mit der Endung *.msk? |
Re: Problem mit FindFirst und Dateiendungen
Wie wär's hiermit:
Delphi-Quellcode:
...
if UpperCase(ExtractFileExt(SR.Name))= '.MSK' then List.Add(Directory + SR.Name); ... |
Re: Problem mit FindFirst und Dateiendungen
Moin Helmi,
als Ergängzung zu Evangelias Beitrag: Merk' Dir am Besten die übergebenen Maske.
Delphi-Quellcode:
Dann musst Du das nur einmal machen.
var
sMsk : string; begin sMsk := UpperCase(ExtractFileExt(Mask)); //... end; Aber eines noch: Das
Delphi-Quellcode:
geht ja nun garnicht ;-)
faAnyfile - faDirectory
(auch wenn es in diesem Falle funktioniert). Es handelt sich hier um Bitwerte. Wenn Du nun also einen rausrechnen willst dann mit and not
Delphi-Quellcode:
faAnyFile and not faDirectory
|
Re: Problem mit FindFirst und Dateiendungen
Zitat:
Denn für was gib ich denn dann bei FindFirst die Endung an?
Delphi-Quellcode:
FindFirst(Directory + Mask, faAnyFile - faDirectory, SR) = 0
|
Re: Problem mit FindFirst und Dateiendungen
Hallo Helmi,
der Grund für das Verhalten von FindFirst/FindNext ist die Unterstützung der "alten" Dateinamen im 8.3-Format. Windows speichert zu jedem langen Dateinamen auch den passenden kurzen Dateinamen und überprüft diesen bei einer Suche ebenfalls. Der Namensanteil wird dabei mit einer Tilde (~) und einer fortlaufenden Nummer versehen, die Erweiterung nach 3 Zeichen abgeschnitten. Die einzige Abhilfe hat dir litsa bereits genannt: eine zusätzliche Überprüfung der gefundenen Dateien. Wenn du dann noch das Funktionsergebnis beim Aufruf von IncludeTrailingPathDelimiter verwertest und Christians Hinweis berücksichtigst, dann sollte es funktionieren:
Delphi-Quellcode:
Gruß Hawkeye
procedure GetFilesInDirectory(Directory: String; const Mask: String; List: TStrings);
var ext : string; // neu SR: TSearchRec; begin List.BeginUpdate; try List.Clear; If Directory <> '' then begin ext := ExtractFileExt(Mask); // neu Directory := IncludeTrailingPathDelimiter(Directory); // Funktionsergebnis nicht verwerfen! If FindFirst(Directory + Mask, faAnyFile and (not faDirectory), SR) = 0 then // Hinweis von Christian try repeat if SameText(ExtractFileExt(SR.Name), ext) then // neu List.Add(Directory + SR.Name) until FindNext(SR) <> 0; finally FindClose(SR); end; end; finally List.EndUpdate; end; end; |
Re: Problem mit FindFirst und Dateiendungen
mir ist so etwas aufgefallen, wenn die Mask mehr als 3 Zeichen hat also wie bei deinem Beispiel .msk2 (4 Zeichen)
Bei .ms1 .ms2 .ms3 klappt das bei mir. Gruß, bluescreen25 |
Re: Problem mit FindFirst und Dateiendungen
Hallo,
danke für die Tips! Ich hab mir jetzt aber fongendes überlegt: Wenn ich sowieso ein zweites mal prüfen muss ob die Endung pass, dann kann ich ja bei FindFirst alle Dateien suchen lassen (*.*):
Delphi-Quellcode:
So brauch ich mir die Endung nicht speichern.
procedure GetFilesInDirectory(Directory: String; const Ext: String; List: TStrings);
var SR: TSearchRec; begin List.BeginUpdate; try List.Clear; If Directory <> '' then begin Directory := IncludeTrailingPathDelimiter(Directory); If FindFirst(Directory + '*.*', faAnyFile and (not faDirectory), SR) = 0 then //hier try repeat If UpperCase(ExtractFileExt(SR.Name))= UpperCase(Ext) then List.Add(Directory + SR.Name); until FindNext(SR) <> 0; finally FindClose(SR); end; end; finally List.EndUpdate; end; end; einzigste Änderung im normalen Code: anstatt "*.msk*, muss ich jetzt ".msk" schreiben |
Re: Problem mit FindFirst und Dateiendungen
Moin Helmi,
Zitat:
Wenn übrigens so
Delphi-Quellcode:
kann die Maske auch mehrere Endungen enthalten (z.B. '.txt.lst'), wenn dann auch nicht mit Wildcards
pos(UpperCase(ExtractFileExt(sr.Name)),ext) > 0
|
Re: Problem mit FindFirst und Dateiendungen
Hallo Helmi,
Zitat:
Zitat:
Ich habe noch etwas festgestellt: bei der Verwendung von Jokerzeichen ('?' bzw. '*') in der Maske für die Namenserweiterung darf kein Vergleich der Extensions stattfinden, weil dieser Vergleich immer fehlschlagen würde. Die notwendigen Änderungen habe ich im folgenden Quelltext markiert:
Delphi-Quellcode:
Ein Mangel läßt sich auf diesem Weg nicht so einfach umgehen: eine Maske wie '*.m??' liefert dir auch Dateinamen, deren Extension nicht genau drei Zeichen enthält.
procedure GetFilesInDirectory(Directory: String; const Mask: String; List: TStrings);
var ext : string; wild : Boolean; // neu SR: TSearchRec; begin List.BeginUpdate; try List.Clear; If Directory <> '' then begin ext := ExtractFileExt(Mask); wild := (Pos('?', ext) > 0) or (Pos('*', ext) > 0); // neu Directory := IncludeTrailingPathDelimiter(Directory); If FindFirst(Directory + Mask, faAnyFile and (not faDirectory), SR) = 0 then try repeat if wild or SameText(ExtractFileExt(SR.Name), ext) then // geändert List.Add(Directory + SR.Name) until FindNext(SR) <> 0; finally FindClose(SR); end; end; finally List.EndUpdate; end; end; Auch wenn du nicht alle Features der Routine im aktuellen Projekt brauchst, solltest du sie nicht entfernen - sie stören ja nicht. Irgendwann benötigst du sie vielleicht, und dann kannst du diese Funktion ohne Änderung wiederverwenden. Gruß Hawkeye |
Re: Problem mit FindFirst und Dateiendungen
Bin grad über diesen Bug gestolpert.
In meinem Fall: FindFirst('*.dpr'...) findet sowohl .dpr-Dateien als auch .dproj-Dateien. Ist ja bizarr! Lustigerweise ist der Bug schon sehr lang bekannt. (siehe ![]() Schon komisch dass das nicht mal in der Delphi-Hilfe Erwähnung findet, damit man sich drauf einstellen kann... Tststs.... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:17 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-2025 by Thomas Breitkreuz