Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Schnelle Methode, um eine Dateiliste zu erstellen (https://www.delphipraxis.net/207087-schnelle-methode-um-eine-dateiliste-zu-erstellen.html)

Blup 24. Feb 2021 10:10

AW: Schnelle Methode, um eine Dateiliste zu erstellen
 
Zitat:

Zitat von Jumpy (Beitrag 1483669)
Keine Ahnung ob das schneller ist, aber könnte man nicht erst nur nach Verzeichnissen suchen, die den Kriterien entsprechen und diese in eine Liste schreiben und dann anschließen in allen Verzeichnissen in dieser Liste die Dateien suchen?

Ist auf jeden Fall langsamer, da jedes Verzeichnis zwei mal durchsuncht wird.

Uwe Raabe 24. Feb 2021 10:14

AW: Schnelle Methode, um eine Dateiliste zu erstellen
 
Ich bin mir nicht sicher, ob ich das richtig verstanden habe, aber hier mal ein Entwurf mit Verwendung der System.IOUtils. Erstmal ungetestet und ohne Berücksichtigung der Performance.

Delphi-Quellcode:
procedure ListFiles(const Root: string; LstInclude, LstExclude, Target: TStrings);
var
  path: string;
  S: string;
  skip: Boolean;
begin
  if (LstInclude <> nil) and (LstInclude.Count > 0) then begin { Includes vorhanden? }
    for path in LstInclude do
      Target.AddStrings(TDirectory.GetFiles(TPath.Combine(Root, path), '*.*', TSearchOption.soAllDirectories));
  end
  else if (LstExclude <> nil) and (LstExclude.Count > 0) then begin { Excludes vorhanden? }
    for path in TDirectory.GetDirectories(Root, '*', TSearchOption.soAllDirectories) do begin
      { ist es ein Exclude Path? }
      skip := False;
      for S in LstExclude do
        if path.StartsWith(TPath.Combine(Root, S), True) then begin
          skip := True;
          Break;
        end;
      if not skip then
        Target.AddStrings(TDirectory.GetFiles(path, '*.*', TSearchOption.soTopDirectoryOnly));
    end;
  end
  else begin { keine Einschränkungen }
    Target.AddStrings(TDirectory.GetFiles(Root, '*.*', TSearchOption.soAllDirectories));
  end;
end;

DieDolly 24. Feb 2021 10:26

AW: Schnelle Methode, um eine Dateiliste zu erstellen
 
Ich teste das gleich mal durch. Auf den ersten Blick kann man nur Pfade in die Listen hinzufügen.
Was muss ich abändern, damit man auch Dateien einfügen kann?

Die Listen können Datei-Pfade enthalten.

Wenn ich das Root E:\ habe und in E der Ordner Dateien ist, dort drin eine Datei Test.txt, diese möchte ich gerne ein- oder ausschließen können, den Rest der Dateien in diesem Ordner aber nicht.
Zeitgleich natürlich auch ganze Verzeichnisse so wie es jetzt schon ist.

Ist das hier ok?
Delphi-Quellcode:
function IsDirectory(const aFileName: string): Boolean;
var
 R: DWORD;
begin
 R := GetFileAttributes(PChar(aFileName));
 Result := (R <> DWORD(-1)) and ((R and FILE_ATTRIBUTE_DIRECTORY) <> 0);
end;

   for path in LstInclude do
    begin
     if IsDirectory(TPath.Combine(Root, path)) then
      Target.AddStrings(TDirectory.GetFiles(TPath.Combine(Root, path), '*.*', TSearchOption.soAllDirectories))
     else
      Target.Add(TPath.Combine(Root, path));
    end;

Andreas13 24. Feb 2021 10:35

AW: Schnelle Methode, um eine Dateiliste zu erstellen
 
Hallo Uwe,
In 3 Zeilen
Delphi-Quellcode:
Target.AddStrings(TDirectory.GetFiles(TPath.Combine(Root, path), '*.*', TSearchOption.soAllDirectories));
..
Target.AddStrings(TDirectory.GetFiles(path, '*.*', TSearchOption.soTopDirectoryOnly));
..
Target.AddStrings(TDirectory.GetFiles(Root, '*.*', TSearchOption.soAllDirectories));
gibt XE5 kommt folgende Fehlermeldung:
[dcc32 Fehler] PDBiA_System.pas(1309): E2250 Es gibt keine überladene Version von 'AddStrings', die man mit diesen Argumenten aufrufen kann

Was müßte ich an Deinem Code ändern, damit es auch bei XE5 funktioniert?
Danke im Voraus!
Gruß, Andreas

Uwe Raabe 24. Feb 2021 10:42

AW: Schnelle Methode, um eine Dateiliste zu erstellen
 
Zitat:

Zitat von Andreas13 (Beitrag 1483677)
Was müßte ich an Deinem Code ändern, damit es auch bei XE5 funktioniert?

Z.B. einen Class-Helper schreiben, der ein AddStrings für ein string-Array unterstützt.

DieDolly 24. Feb 2021 10:46

AW: Schnelle Methode, um eine Dateiliste zu erstellen
 
Bei LstExclude bleibt Target leider leer. Wenn ich Dateien\Test.txt in LstExclude hinzufüge, bleibt die Liste komplett leer.
Änderre ich TDirectory.GetDirectories zu TDirectory.GetFiles ab, funktioniert es. Aber ist das noch so gewollt?

Hier meine Änderungen, damit auch Dateien funktionieren
Delphi-Quellcode:
function IsDirectory(const aFileName: string): Boolean;
var
 R: DWORD;
begin
 R := GetFileAttributes(PChar(aFileName));
 Result := (R <> DWORD(-1)) and ((R and FILE_ATTRIBUTE_DIRECTORY) <> 0);
end;

procedure ListFiles(const Root: string; LstInclude, LstExclude, Target: TStrings);
var
 path: string;
 S: string;
 skip: Boolean;
begin
 if (LstInclude <> nil) and (LstInclude.Count > 0) then
  begin {Includes vorhanden?}
   for path in LstInclude do
    begin
     if IsDirectory(TPath.Combine(Root, path)) then
      Target.AddStrings(TDirectory.GetFiles(TPath.Combine(Root, path), '*.*', TSearchOption.soAllDirectories))
     else
      Target.Add(TPath.Combine(Root, path));
    end;
  end
 else if (LstExclude <> nil) and (LstExclude.Count > 0) then
  begin {Excludes vorhanden?}
   for path in TDirectory.GetFiles(Root, '*.*', TSearchOption.soAllDirectories) do
    begin
     {ist es ein Exclude Path?}

     for S in LstExclude do
      begin
       skip := False;
       if path.StartsWith(TPath.Combine(Root, S), True) then
        begin
         skip := True;
         Break;
        end;
      end;

     if not skip then
      begin
       if IsDirectory(TPath.Combine(Root, path)) then
        Target.AddStrings(TDirectory.GetFiles(path, '*.*', TSearchOption.soTopDirectoryOnly))
       else
        Target.Add(TPath.Combine(Root, path));
      end;
    end;
  end
 else
  begin {keine Einschränkungen}
   Target.AddStrings(TDirectory.GetFiles(Root, '*.*', TSearchOption.soAllDirectories));
  end;
end;

Uwe Raabe 24. Feb 2021 11:30

AW: Schnelle Methode, um eine Dateiliste zu erstellen
 
Die Anforderung, dass die Listen auch Dateinamen (oder womöglich auch Wildcards) enthalten können, macht einen geänderten Ansatz notwendig. Deine Änderungen weichen zu stark von meinem Vorschlag ab, als dass das noch funktionieren würde.

DieDolly 24. Feb 2021 11:45

AW: Schnelle Methode, um eine Dateiliste zu erstellen
 
Schade :( dann weiß ich leider nicht weiter als mit FindFirst und FindNext, was aber wieder langsam ist wenn ich das mache weil ich alle Dateien durchgehe.

Schade weil... ich habe noch ein altes Programm rumliegen (nur die ausführbare Datei) wo so ein alter Code von mir angewendet wird.
Bei meiner Festplatte P:\ (portable programme, 66 Verzeichnisse, 1 soll in die LstInclude-List) dauert das 10 Sekunden.
Mit deinem Code und meinen (schlechten) Änderungen, 12 Millisekunden!

jaenicke 24. Feb 2021 12:31

AW: Schnelle Methode, um eine Dateiliste zu erstellen
 
Die schnellste Variante wäre es so zu machen wie Everything und andere Tools:
Direkt auf die NTFS Datenbank zugreifen.

Damit kann man innerhalb von Millisekunden selbst Partitionen mit vielen Dateien durchsuchen.
https://blogs.msmvps.com/bsonnino/20...fs-structures/

Leider braucht man dafür Adminrechte und es ist auch nicht so einfach.

DieDolly 24. Feb 2021 12:43

AW: Schnelle Methode, um eine Dateiliste zu erstellen
 
Adminrechte sind ausgeschlossen, da ich Zugriff auf Netzlaufwerke brauche.
Uwe's Lösung ist schon wahnsinnig schnell, jetzt fehlen nur noch Wildcards. Dateien hab ich schon ergänzt.
Für Wildcards kenne ich nur PathMatchSpecW.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:06 Uhr.
Seite 2 von 3     12 3      

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