![]() |
Dateiliste gefiltert erstellen
Der Titel klingt vielleicht etwas komisch. Aber grob erklärt.
Mit Winapi.Windows.FindFirstFileEx, ganz normal wie man das so kennt, gehe ich durch ein Verzeichnis. Zu jeder Datei und jedem Verzeichnis erstelle ich ein Objekt, welches in eine Liste kommt. Das funktioniert rasend schnell und reicht mir vollkommen so wie es ist. Ich möchte aber bevor ein Objekt überhaupt erstellt wird prüfen, ob der Dateiname bei dem FindFirstFileEx() gerade dran ist in einer zweiten Liste vorkommt. Falls ja, soll das Objekt am Ende nicht erzeugt werden. Die zweite Liste enthält nur halbe Pfade also beispielsweise so Sub1\Sub2\File1.exe FileX.exe Sub1\FileY.exe Das Hauptverzeichnis speichere ich dort nicht mit, da das zu große Dateien zum Speichern geben würde. Wie kann ich mit Winapi.Windows.FindFirstFileEx() nun Dateien aussortieren, die in der zweiten Liste vorkommen? Bei 1000 Dateien dauert das aktuell 4 Sekunden, wenn ich 400 davon aussortieren lassen möchte. Ohne Aussortieren dauert das Erzeugen der Objekte rund 10 Millisekunden. |
AW: Dateiliste gefiltert erstellen
Ich würde zum Filtern nicht mehr direkt die WinAPI verwenden sondern nur noch TDirectory.GetFiles.
Delphi-Quellcode:
Predicate kann dann noch mehr filtern. Beispiel:
ListOfFromFiles := TDirectory.GetFiles(FCopyFrom, '*', TSearchOption.soAllDirectories, Predicate);
Delphi-Quellcode:
Predicate :=
function(const Path: string; const SearchRec: TSearchRec): Boolean begin Result := not string(SearchRec.Name).IsEmpty; end; |
AW: Dateiliste gefiltert erstellen
Wie lässt sich GetFiles mit meiner zweiten Liste kombinieren?
|
AW: Dateiliste gefiltert erstellen
* Ein
![]() * Am Einfachsten mit ![]()
Delphi-Quellcode:
wobei hier natürlich wäre direkt
EndsText('FileX.exe', 'C:\dir\FileX.exe') = True
EndsText('FileX.exe', 'C:\dir\absadsadFileX.exe') = True EndsText('\' + 'FileX.exe', 'C:\dir\absadsadFileX.exe') = False
Delphi-Quellcode:
besser
if ExtractFilenName('C:\dir\FileX.exe') = 'FileX.exe'
bzw.
Delphi-Quellcode:
if MatchText(ExtractFilenName('C:\dir\FileX.exe'), ['FileX.exe', Xyz.exe])
aber
Delphi-Quellcode:
EndsText('dir\FileX.exe', 'C:\dir\FileX.exe') = True
EndsText('dir\FileX.exe', 'C:\absadsaddir\FileX.exe') = True EndsText('\' + 'dir\FileX.exe', 'C:\absadsaddir\FileX.exe') = False
Delphi-Quellcode:
FileNamenArray := TDirectory.GetFiles('C:\dir', '*.*', TSearchOption.soAllDirectories,
procedure (const Path: string; const SearchRec: TSearchRec): Boolean begin // SearchRec.Name = nur der Dateiname // TPath.Combine(Path, SearchRec.Name) = vollsändiger Pfad Result := True wenn Pfad im ergebnis sein soll. // es geht auch Result := False; und selbst irgendwo in einer externen Liste speichern oder direkt verarbeiten end); |
AW: Dateiliste gefiltert erstellen
Zitat:
Der Teilstring ist kein Problem. Ich kann das Hauptverzeichnis einfach vorne dranhängen! |
AW: Dateiliste gefiltert erstellen
Ich stelle mir gerade die Frage, ob es nicht eigentlich schneller wäre die Dateiliste einfach zu erzeugen ohne irgendwas rauszufiltern.
Kann man dann beide Listen miteinander vergleichen und Einträge aus Dateiliste löschen die in Filterliste vorhanden sind, ohne jeden Eintrag von beiden Listen miteinander zu vergleichen? Beispiel: Dateiliste (existierende Dateien): C:\File1.exe C:\File2.exe C:\File3.exe C:\Sub1\Sub2\File1.exe C:\FileX.exe C:\Sub1\FileY.exe C:\File4.exe C:\File5.exe Filterliste (auf Dateiliste anwenden): C:\Sub1\Sub2\File1.exe C:\FileX.exe C:\Sub1\FileY.exe Am Ende dürfte also nur übrig bleiben: C:\File1.exe C:\File2.exe C:\File3.exe C:\File4.exe C:\File5.exe |
AW: Dateiliste gefiltert erstellen
Hallo,
bau dir eine einfache HashListe mit HashItems (mit Key=Dateiname und Path-Eigenschaft im HashItem). Der Vergleich letztendlich geht dann super schnell. Beste Grüße |
AW: Dateiliste gefiltert erstellen
Ich kann das System nicht mehr umstellen. Eine neue Liste kann ich erstellen weil ich dann wochenlang beschäftigt wäre alles abzuändern.
Die Listen sind nicht das Problem, das Erstellen ist superschnell. Das vergleichen dauert ewig, deswegen meine Idee oben. Bitte durchlesen. |
AW: Dateiliste gefiltert erstellen
Ok, wie findest du File1.exe von Liste1 in Liste2 ?
|
AW: Dateiliste gefiltert erstellen
Anders erklärt.
Die Dateiliste A wird von Winapi.Windows.FindFirstFileEx() erstellt. Das sind alle Dateien in einem Verzeichnis. Filterliste B sind ein paar Einträge von Dateien, die am Ende nicht in A landen sollen. Das funktioniert ja alles schon, aber ist langsam. Weil jeder Fund von Winapi.Windows.FindFirstFileEx() iteriert die komplette Liste B durch. Meine Idee wäre jetzt, die Dateiliste A erstmal ohne Filterung komplett zu erstellen und erst danach A und B zu vergleichen. Alles aus B soll dann aus A verschwinden. Fast vergessen. Da die Liste A Objekte enthält, muss ich da nicht zwangsläufig Einträge rauslöschen. Man könnte auch einfach eine Flag setzen, sodass die im späteren Verlauf ignoriert werden. Das würde der vorhandene Code zulassen. Zusammengefasst: beide Listen existieren, das Zusammenstellen der Listen ist rasendschnell und schnell genug. Es hapert nur beim Vegleich. Weil Wenn Liste A 15.000 Einträge hat und B 1000, sind das, wenn man jeden Eintrag mit jedem vergleicht, sehr viele Vergleiche, viele davon mehr als unnötig. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:56 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