AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Schnellste Möglichkeit einen Verzeichnisbaum einzulesen
Thema durchsuchen
Ansicht
Themen-Optionen

Schnellste Möglichkeit einen Verzeichnisbaum einzulesen

Ein Thema von Hobbycoder · begonnen am 10. Dez 2024 · letzter Beitrag vom 11. Dez 2024
Antwort Antwort
Seite 1 von 2  1 2      
Hobbycoder

Registriert seit: 22. Feb 2017
984 Beiträge
 
#1

Schnellste Möglichkeit einen Verzeichnisbaum einzulesen

  Alt 10. Dez 2024, 10:50
Hi,

ich muss einen Verzeichnisbaum einlesen und dabei Dateinamen, Dateigröße und Erstellungsdatum einlesen und mit einer Datenbank abgleichen. Tatsächlich handelt es sich nur um 2 Verzeichnisebenen. Allerdings immer über Netzwerk.
Zur Zeit nutze ich FindFirst/FindNext, und das dann recursiv. Es handelt ich ca. um 37000 Dateien.
Leider dauert das verhältnismäßig lange im Vergleich zur danach folgenden Datenbankoperation.

Gibt es schon signifikant schnellere Möglichkeiten, oder ist da nicht mehr viel rauszuholen?

Delphi-Quellcode:
procedure TThreadLoadBilderArchivieren.BilderEinlesen(
  Pfad: string);
var
  sr: TSearchRec;
  b: TBild;
begin
  if self.Terminated then Exit;
  if FindFirst(Pfad+'*.*', faAnyFile, sr)=0 then
  repeat
    if (sr.Name<>'.') and (sr.Name<>'..') and (LowerCase(sr.Name)<>'thumbs.db') then
    begin
      if sr.Attr and faDirectory = faDirectory then
      begin
        BilderEinlesen(Pfad+sr.Name+'\');
      end else begin
        if ExtractFileExt(sr.Name)<>'.tmbthen
        begin
          b:=TBild.Create;
          b.lfdnr:=0;
          b.Pfad:=Pfad+sr.Name;
          b.Dateidatum:=FileDateToDateTime(sr.Time);
          b.Groesse:=sr.size;
          FBildList.Add(b);
        end;
      end;
    end;
    if self.Terminated then Break;
  until FindNext(sr)<>0;
  sysutils.FindClose(sr);
end;
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.

Geändert von Hobbycoder (10. Dez 2024 um 10:52 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.238 Beiträge
 
Delphi 12 Athens
 
#2

AW: Schnellste Möglichkeit einen Verzeichnisbaum einzulesen

  Alt 10. Dez 2024, 10:55
Nimm direkt die WinAPI Bei Google suchenFindFirstFile und da gibt es Optionen, um Zusatzinfos wegzulassen (vor allem den 8.3-Dateiname), die Sortierung des Treibers und "LargeFetch".


PS: Aktuelle Delphis haben im TSearchRec ein Property, was dir direkt den TDateTime gibt. (ohne manuelles FileDateToDateTime)
https://docwiki.embarcadero.com/Libr...ils.TSearchRec

Tipp: Vielleicht nicht unbedingt schneller, aber "einfacher":
Delphi-Referenz durchsuchenTDirectory.GetFiles
https://www.delphipraxis.net/216317-...ei-finden.html
$2B or not $2B

Geändert von himitsu (10. Dez 2024 um 10:59 Uhr)
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
984 Beiträge
 
#3

AW: Schnellste Möglichkeit einen Verzeichnisbaum einzulesen

  Alt 10. Dez 2024, 11:01
Danke

Zitat:
PS: Aktuelle Delphis haben im TSearchRec ein Property, was dir direkt den TDateTime gibt. (ohne manuelles FileDateToDateTime)
https://docwiki.embarcadero.com/Libr...ils.TSearchRec

Tipp: Vielleicht nicht unbedingt schneller, aber "einfacher":
Delphi-Referenz durchsuchenTDirectory.GetFiles
Leider noch auf einem alten D7
Aber die WinAPI werd ich mal ausprobieren.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.238 Beiträge
 
Delphi 12 Athens
 
#4

AW: Schnellste Möglichkeit einen Verzeichnisbaum einzulesen

  Alt 10. Dez 2024, 11:06
Leider noch auf einem alten D7
https://www.embarcadero.com/de/products/delphi/starter

https://www.delphipraxis.net/profile.php?do=editprofile da unten kann man was angeben


Und wegen Delphi 7:
Die Unicode-Version (W), nicht ANSI (A).

Bzw. direkt MSDN-Library durchsuchenFindFirstFileExW mit BasicLevel anstatt MSDN-Library durchsuchenFindFirstFileW.
$2B or not $2B

Geändert von himitsu (10. Dez 2024 um 11:13 Uhr)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.532 Beiträge
 
Delphi 7 Professional
 
#5

AW: Schnellste Möglichkeit einen Verzeichnisbaum einzulesen

  Alt 10. Dez 2024, 11:21
Kannst Du mal vergleichen, ob deine Routine lokal (mit der passender Datenmenge) deutlich schneller ist, als über das Netz.

Meine D7-Variante für rekursives Dateiensuchen sieht Deiner Routine verblüffend ähnlich und ist sehr schnell. Den Flaschenhals vermute ich daher im Netzwerkzugriff und nicht in Deiner Routine.
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
984 Beiträge
 
#6

AW: Schnellste Möglichkeit einen Verzeichnisbaum einzulesen

  Alt 10. Dez 2024, 15:50
Ist mir bekannt. Ist aber ein altes Projekt, dass ich jetzt nicht deswegen komplett überarbeiten will.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
984 Beiträge
 
#7

AW: Schnellste Möglichkeit einen Verzeichnisbaum einzulesen

  Alt 10. Dez 2024, 15:54
Kannst Du mal vergleichen, ob deine Routine lokal (mit der passender Datenmenge) deutlich schneller ist, als über das Netz.

Meine D7-Variante für rekursives Dateiensuchen sieht Deiner Routine verblüffend ähnlich und ist sehr schnell. Den Flaschenhals vermute ich daher im Netzwerkzugriff und nicht in Deiner Routine.
So unterschiedlich können recursive Methoden, die FindFist/FindNext nutzen, nicht aussehen

Ist möglich. Aber das Netzwerk beim Kunden liegt nicht unter meiner Kontrolle. Das muss ich in dem Fall so nehmen wie es ist.
Ich kann (will) mir jetzt aber auch nicht die ganzen 37000 Dateien rüberholen um das bei mir zu testen
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.532 Beiträge
 
Delphi 7 Professional
 
#8

AW: Schnellste Möglichkeit einen Verzeichnisbaum einzulesen

  Alt 10. Dez 2024, 19:00
Du muss Dir ja nicht die Dateien des Kunden holen, es reicht ja, wenn Du Dir einen passenden Verzeichnisbaum mit (durchaus auch leeren Dateien) anlegst.

Oder nimm einfach Laufwerk C: und miss die Zeit. Zeit durch Anzahl Dateien = Durchschnittswert * 37.000 wäre die zu erwartende Zeit. Gibt's da große Unterschiede oder ist das eher vernachlässigbar? Große Unterschiede hieße für mich, dass der Flaschenhals eher im Netzwerk zu suchen ist, andernfalls in Deiner Routine.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.748 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Schnellste Möglichkeit einen Verzeichnisbaum einzulesen

  Alt 10. Dez 2024, 21:20
Der Flaschenhals ist hier die Latenz beim Zugriff auf den Server. Es wird für jeden Abruf der jeweils nächsten Datei eine Anfrage an den Server geschickt und darauf gewartet.

Lösen kann man das auf zwei Wegen:
  • Du kannst die Abfrage mit mehreren Threads erledigen, indem du z.B. einen Thread pro Anfangsbuchstabe erstellst oder einen pro Unterverzeichnis oder ähnliches, je nachdem was passt. Anders als bei lokalen Abfragen ist die eingesparte Wartezeit auf die Antworten des Servers größer als die Verlangsamung durch parallele Abfragen ins Dateisystem. In aktuellen Delphis kann man dafür TTask oder parallel for verwenden, bei Delphi 7 kannst du TThread nutzen.
  • Am besten ist aber die Nutzung einer SMB-Bibliothek wie libsmb2. Diese hat den großen Vorteil, dass smb2_opendir und smb2_readdir die Dateiinformationen direkt in einem Puffer abrufen, so dass nicht bei jeder Datei einzeln eine Anfrage an den Server geschickt wird. Wenn man den verwendeten Puffer im System noch erhöhen kann, erhöht sich die Geschwindigkeit zusätzlich.
    Die Implementierung ist relativ einfach, da nur ein paar exportierte Funktionen und Strukturen übersetzt werden müssen.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
984 Beiträge
 
#10

AW: Schnellste Möglichkeit einen Verzeichnisbaum einzulesen

  Alt 11. Dez 2024, 11:47
Am besten ist aber die Nutzung einer SMB-Bibliothek wie libsmb2. Diese hat den großen Vorteil, dass smb2_opendir und smb2_readdir die Dateiinformationen direkt in einem Puffer abrufen, so dass nicht bei jeder Datei einzeln eine Anfrage an den Server geschickt wird. Wenn man den verwendeten Puffer im System noch erhöhen kann, erhöht sich die Geschwindigkeit zusätzlich.
Die Implementierung ist relativ einfach, da nur ein paar exportierte Funktionen und Strukturen übersetzt werden müssen.
Das werd ich mal ausprobieren. Klingt sehr gut
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:10 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