AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Optimaler Hash-Algorithmus und Strategie für Dateivergleiche, Verzeichnisbaum
Thema durchsuchen
Ansicht
Themen-Optionen

Optimaler Hash-Algorithmus und Strategie für Dateivergleiche, Verzeichnisbaum

Ein Thema von Rollo62 · begonnen am 3. Mai 2024 · letzter Beitrag vom 11. Mai 2024
Antwort Antwort
Seite 2 von 3     12 3      
Benmik

Registriert seit: 11. Apr 2009
547 Beiträge
 
Delphi 11 Alexandria
 
#11

AW: Optimaler Hash-Algorithmus und Strategie für Dateivergleiche, Verzeichnisbaum

  Alt 3. Mai 2024, 21:01
Ich möchte deine Aufmerksamkeit auf xxHash richten, das ich mittlerweile statt MD5 verwende. Die Seite von Cyan4973 auf Github ist interessant, ich habe den Wrapper von YWtheGod (auch auf Github) genommen.
Ich fand es auch günstig, zunächst nur den Anfang zweier Dateien zu vergleichen, insbesondere bei sehr großen Dateien. Da unter Windows immer mindestens 256 KB eingelesen werden, lese und vergleiche ich zunächst einmal diese ersten 256 KB, was schon einmal so gut wie alle nicht gleichen Dateien aussieben sollte.
Bei mir sind Hardlinks ein Thema, weswegen ich auch mittels GetFileInformationByHandle die FileID ermittle und vergleiche.
Mir haben auch die Hinweise von Uwe Raabe und Andreas Hausladen sehr geholfen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: Optimaler Hash-Algorithmus und Strategie für Dateivergleiche, Verzeichnisbaum

  Alt 4. Mai 2024, 09:24
Es geht hier doch garnicht um extreme Sicherheit,
es geht auch nicht um Vergleiche "ähnlicher" Dateien,
sondern nur um Ändernung jeweils einzelner Dateien mit sich selbst,
womit die Möglichkeit extrem selten vorkommender Hash-Kollisionen sehr unwahrscheinlich ist, vor allem, wenn niemand (Hacker und Co.) absichtlich die Datei gezielt und mit enormem Aufwand daraufhin ändert.

* das Archiv-Attribut
* Datum des letzten Schreibzugriffs
* und ansonsten sind doch immernoch MD5/SHA1/SHA256 ausreichend

System.Hash :
THashMD5 (128)
THashSHA1 (128)
THashSHA2 (224,256,384,512)
THashBobJenkins (32, verwendet Dlelphi für Listen)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 4. Mai 2024 um 09:30 Uhr)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.434 Beiträge
 
Delphi 7 Professional
 
#13

AW: Optimaler Hash-Algorithmus und Strategie für Dateivergleiche, Verzeichnisbaum

  Alt 4. Mai 2024, 10:30
Hab' einfach mal wieder die KI meiner Wahl befragt:
Zitat von Frage:
Wie hoch ist die Wahrscheinlichkeit, dass es bei der Verwendung eines MD5-Hashes beim Vergleich von Dateien zu einer Kollision kommt, d. h., das zwei unterschieldiche Dateien über einen identischen MD5-Hash verfügen?
Zitat von Antwort:
Die Wahrscheinlichkeit einer Kollision bei der Verwendung von MD5-Hashes hängt von der Anzahl der eindeutigen Eingaben ab, die gehasht werden. MD5 erzeugt einen Hash-Wert von 128 Bit, was bedeutet, dass es 2^128 oder etwa 3.4 x 10^38 eindeutige Hash-Werte gibt.

Die Wahrscheinlichkeit einer Kollision kann mit der Geburtstagsparadoxon-Formel berechnet werden. Wenn wir n als die Anzahl der eindeutigen Eingaben und d als die Anzahl der möglichen Hash-Werte betrachten, dann ist die Wahrscheinlichkeit P einer Kollision gegeben durch:

P ≈ n^2 / 2d

Für MD5, wenn wir annehmen, dass wir etwa 2^64 eindeutige Eingaben hashen (eine große, aber realistische Anzahl), dann ist die Wahrscheinlichkeit einer Kollision:

P ≈ (2^64)^2 / 2 * 2^128 = 1 / 2^64

Das ist eine sehr kleine Wahrscheinlichkeit, aber es ist nicht null. In der Praxis sind Kollisionen mit MD5 bekannt und das Verfahren wird daher für sicherheitskritische Anwendungen nicht mehr empfohlen. Es ist jedoch immer noch weit verbreitet für weniger kritische Anwendungen wie die Überprüfung der Integrität von Dateien.

Bitte beachten Sie, dass diese Berechnung eine Vereinfachung ist und die tatsächliche Wahrscheinlichkeit aufgrund verschiedener Faktoren, einschließlich der spezifischen Eigenschaften des MD5-Algorithmus, abweichen kann. Es ist auch wichtig zu beachten, dass selbst eine sehr geringe Kollisionswahrscheinlichkeit in bestimmten Kontexten ein Sicherheitsrisiko darstellen kann.
Zitat von Frage:
Wie verändert sich bei einem Dateivergleich die Wahrscheinlichkeit einer MD5-Hash-Kollision, wenn zusätzlich noch die Dateigröße und das Datum der letzten Dateiänderung mit berücksichtigt werden?
Zitat von Antwort:
Die Berücksichtigung zusätzlicher Informationen wie Dateigröße und Datum der letzten Änderung kann die Wahrscheinlichkeit einer Kollision beim Vergleich von Dateien erheblich reduzieren.

Wenn zwei Dateien denselben MD5-Hash haben, aber unterschiedliche Größen oder Änderungsdaten, dann können wir sicher sein, dass es sich um unterschiedliche Dateien handelt, auch wenn der MD5-Hash identisch ist. In diesem Fall würde die Kollision beim MD5-Hash nicht zu einer falschen Übereinstimmung führen, da die zusätzlichen Informationen (Dateigröße und Änderungsdatum) die Unterschiede aufzeigen.

Es ist jedoch wichtig zu beachten, dass diese Methode nicht vollständig vor Kollisionen schützt. Es ist theoretisch möglich (wenn auch extrem unwahrscheinlich), dass zwei unterschiedliche Dateien denselben MD5-Hash, dieselbe Größe und dasselbe Änderungsdatum haben. Aber die Wahrscheinlichkeit dafür ist so gering, dass sie in der Praxis vernachlässigbar ist.

Insgesamt kann die Berücksichtigung von Dateigröße und Änderungsdatum bei der Verwendung von MD5-Hashes zur Dateivergleichung die Sicherheit erheblich verbessern. Es ist jedoch immer noch empfehlenswert, sicherere Hash-Funktionen wie SHA-256 zu verwenden, insbesondere für sicherheitskritische Anwendungen.
Zitat von Frage:
Es ist aber doch im Rahmen des Möglichen, dass zwei Dateien mit gleichem MD5-Hash und identischer Dateigröße, aber unterschiedlichen Änderungszeitpunkten identisch sind, z. B. weil eine Datei von einem Datenträger auf einen andern kopiert wurde oder nur ein Kopieren unter einem anderen Dateinamen oder in ein anderes Verzeichnis erfolgte. Wäre es in diesem Falle nicht zielführender zum Vergleich nur Dateigröße und erst bei identischer Dateigröße zusätzlich den MD5-Hash zu verwenden? Wie würde sich dadurch die Wahrscheinlichkeit eines Kollision der MD5-Hashs verändern?
Zitat von Antwort:
Sie haben absolut recht. In der Praxis ist es durchaus möglich, dass zwei Dateien mit demselben MD5-Hash und der gleichen Größe, aber unterschiedlichen Änderungsdaten tatsächlich identisch sind. Dies könnte der Fall sein, wenn eine Datei kopiert oder unter einem anderen Namen gespeichert wurde.

In solchen Fällen könnte es sinnvoll sein, zuerst die Dateigröße zu vergleichen und nur bei Übereinstimmung der Größe den MD5-Hash zu berechnen und zu vergleichen. Dies könnte die Effizienz des Vergleichsprozesses verbessern, insbesondere wenn eine große Anzahl von Dateien verglichen wird, da die Berechnung von Hashes rechenintensiv sein kann.

Was die Wahrscheinlichkeit einer Kollision betrifft, so würde sich diese nicht ändern, da die Wahrscheinlichkeit einer Kollision nur von der Anzahl der eindeutigen Eingaben und der Größe des Hash-Raums abhängt (bei MD5 sind das 2^128 mögliche Hashes). Die Reihenfolge, in der Sie die Größe und den Hash vergleichen, hat keinen Einfluss auf die Wahrscheinlichkeit einer Kollision. Es ändert jedoch die Wahrscheinlichkeit, dass eine Kollision zu einer falschen Übereinstimmung führt, da Dateien mit unterschiedlichen Größen bereits vor der Hash-Berechnung ausgeschlossen werden.

Es ist jedoch wichtig zu beachten, dass diese Methode immer noch nicht vollständig vor Kollisionen schützt. Es ist theoretisch möglich (wenn auch extrem unwahrscheinlich), dass zwei unterschiedliche Dateien denselben MD5-Hash und dieselbe Größe haben. Aber die Wahrscheinlichkeit dafür ist so gering, dass sie in der Praxis vernachlässigbar ist. Für sicherheitskritische Anwendungen wird daher empfohlen, sicherere Hash-Funktionen wie SHA-256 zu verwenden.
Mein Fazit:

Eine Tabelle mit Dateinamen, Dateigröße, MD5-Hash und den Änderungsdaten sollten für die gestellte Aufgabe ausreichend sein.

Das Erstellen einer Baumstruktur ist nicht erforderlich, es sei denn, man möchte es für die Anwender schön aussehen lassen. Dann reicht es aber aus die Baumstruktur nur für die Daten zu erstellen, die die Anwender auch zu Gesicht bekommen sollen und zwar erst dann, wenn die Daten zur Anzeige gebracht werden.

Mein Vorgehen wäre:

Rekursives Einlesen der Verzeichnisstruktur(en) und je Datei Pfad und Name, Dateigröße und Änderungsdaten in einer Tabelle speichern, dazu reichen FindFirst und FindNext mit TSearchRec aus.

In der so erstellten Tabelle alle Sätze suchen, bei denen die Dateigröße mehr als einmal vorkommt:
SQL-Code:
select * from tabelle a where exists (
  select 1 from tabelle b
  where a.dateigroesse = b.dateigroesse
  group by b.dateigroesse having count(*) > 1
)
order by a.Dateigroesse;
Für die so ausgewählten Dateien den MD5-Hash berechnen und in der Tabelle speichern.

Anschließend die Dateien suchen lassen, bei denen die Kombination aus Dateigröße und MD5-Hash mehr als einmal vorkommen.
SQL-Code:
select * from tabelle a where exists (
  select 1 from tabelle b
  where a.dateigroesse = b.dateigroesse
  and a.md5 = b.md5
  group by b.dateigroesse, b.md5 having count(*) > 1
)
order by a.Dateigroesse, a.md5;
Aus dem Ergebnis wird dann die Anzeige für die Anwender befüllt, egal ob als TreeView, ListView oder auch einfach nur in 'nem DBGrid.
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.932 Beiträge
 
Delphi 12 Athens
 
#14

AW: Optimaler Hash-Algorithmus und Strategie für Dateivergleiche, Verzeichnisbaum

  Alt 4. Mai 2024, 11:52
Hallo Delphi.Narium,

ich bin nicht ganz sicher ob Du nur die Hash-Verwaltung beschreibst, oder ob Hash und Tree-Verwaltung zusammen integriert sind.
Ich hatte ja schon geschrieben, dass dies vielleicht zwei verschiedene Aufgaben sind, die man nicht mischen sollte.
Persönlich fände ich das Mischen beider Aufgaben aber sehr sinnvoll, eben weil es dann keine Redundanzen und Fehler durch getrente Datenhaltung auf das gleiche physikalische System geben kann.

Ich meine Du beschreibst das aufnehmen der Hashes in die DB usw., und dann nur am Rande, dass daraus Tree, ListView usw. erstellt werden können.
Welche Struktur schlägst Du denn dafür vor?

Ich sehe dafür erstmal zwei sinnvolle Optionen in einer DB, vielleicht gibt es aber noch weitere:
Delphi-Quellcode:
-- Adjacency List
CREATE TABLE FileSystem (
    id INT PRIMARY KEY,
    parent_id INT,
    name VARCHAR(255),
    hash_value VARCHAR(255),
    type VARCHAR(50),
    FOREIGN KEY (parent_id) REFERENCES FileSystem(id)
);

-- Nested Set
CREATE TABLE FileSystem (
    id INT PRIMARY KEY,
    name VARCHAR(255),
    lft INT,
    rgt INT,
    hash_value VARCHAR(255),
    type VARCHAR(50)
);
In jedem Fall ist der "hash_value" sozusagen nur ein nützliches Abfallprodukt, mit dem sehr schnell verifiziert werden kann,
ob es eine Datei bereits im System gibt und wie oft, unabhängig von der zu Grunde liegenden Baumstruktur.

Das trifft das was ich suche schon ganz gut, danke sehr für die Idee mit der DB, das scheint eine Menge Vorzüge über einer spezifischen Klasse zu haben.

Meine Frage war zu Deiner Erfahrung mit "Adjacency List" bzw. "Nested Set" oder eventuell auch "Flat table" mit kompletten Pfadangaben,
was davon sich für das Durchlaufen von Filesystemen am besten eignet.

Ich muss wahrscheinlich öfters die gesamten Filesysteme abgleichen, eben weil es mehrere Parteien gibt, welche unabhängig voneinander darauf zugreifen können.

Remote-Verzeichniss (es kann mehrere geben)
- ist ein zentrales Filesystem mit entfernten Daten, gehostet auf einem Fileserver im Internet
- es kann durchaus mehrere, redundante oder auch ergänzende Remote-Verzeichnisse geben, auf verschiedenen Servern
- dieses kann auf verschiedenen Wegen bearbeitet werden (z.B. automatisch aus einem anderem Dokumentenmanagementsystem, manuell per Website)
- kann über verschiedene Protokolle bearbeitet werden (z.B. FTP, REST-API, direkt über WebClient auf dem Serversystem)
- das von verschiedenen Parteien aus bearbeitet werden kann (automatische Ausleitungen von verschiedenen Systemen)
- eine Verwaltung von Änderungen, Verzeichnisbaum auf dem Server ist erstmal nicht so ohne Weiteres möglich.
- die Möglichkeit eine DB auf dem Server zu halten, welche das Ganze zentral abbildet, wäre denkbar ist aber auch eher ungewünscht.



Lokal
- ist eine lokale Kopie zur Zusammenführung, Bearbeitung und Analyse spezifischer Daten (lokal um den Server nicht zu belasten)
- die lokale Kopie sollte möglichst nur bei Änderungen aktiv werden, daher die Frage nach Vergleich ganzer Baumstrukturen mit Hash
- insbesondere das Einstellen neuer Dateien soll abgeprüft und verhindert werden (das gleiche File, mit anderem Namen, an andere Stelle).


Eine Möglichkeit wäre noch das Erzeugen und Speichern von Fingerprints (*.md) auf den Servern, was aber auch eher ungewünscht ist.
Die Datenmengen sind jedenfalls nicht so groß, dass eine Synchronisation Remote-Lokal generell ein Problem wäre.


Deshalb trifft der Vergleich zu GIT/GitHub von Benmik schon ganz gut zu, nur eben geht es in erster Linie um binäre Dateien, nicht nur um Text.

Es gäbe noch einen anderen Vergleich, z.B. mit einem FTP-Client, welcher auch Locale und Remote Filesysteme abgleichen kann,
aber nicht unbedingt Änderungen in den Files erkennen kann.

Ich denke der Ansatz mit einer DB ist einen Versuch Wert, das werde ich mal nächste Woche angehen.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.434 Beiträge
 
Delphi 7 Professional
 
#15

AW: Optimaler Hash-Algorithmus und Strategie für Dateivergleiche, Verzeichnisbaum

  Alt 4. Mai 2024, 12:04
Habe momwentan keine Zeit ausführlich zu antworten, bitte hab' da etwas Geduld.

Ja, ich beschreibe nur die Hash-Verwaltung. Einen Baum halte ich für überflüssig. Mir erschließt sich nicht, wofür er nützlich sein sollte, außer für die Anzeige der Daten. Dann kann man ihn mit 'nem Treeview gezielt aus der benötigten Teilmenge der Tabelle erstellen.

Die Baumstruktur für die Anzeige kann man immer "on the fly" aus den Pfadangeaben und dem Dateinamen erstellen und muss sie nicht permanet vorhalten, zumal sie für das Erkennen von Dubletten, ... keinerlei Mehrwert hat.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

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

AW: Optimaler Hash-Algorithmus und Strategie für Dateivergleiche, Verzeichnisbaum

  Alt 4. Mai 2024, 12:13
Zitat:
Das ist eine sehr kleine Wahrscheinlichkeit, aber es ist nicht null
Egal welcher Hash, Kollisionen sind theoretisch immer vorhanden, so lange der Hash kleiner ist, als die Datei.
Selbst wenn der Hash gleich groß wäre, wie die Datei, gäbe es theoretisch immernoch Kollisionen, da ja der Hash einen anderen Wert berechnet, wie die Ursprungsdaten und somit kann ebenfalls bei unterschiedlichen Dateien der Selbe hash entstehen.

Was also bei den Hashs den Unterschied macht, ist wie groß er ist, je größer um so unwahrscheinlicher,
und je besser die Berechnung ist, um unwahrscheinlicher.



Billigster Hash, es werden einfach nur die Bytes in den Speicher geschoben, ohne Rückführung des Überlaufs, dann hat ein 32 Bit Hash schon ab einer Datei von 5 Byte Größe garantiert im ersten Byte alle Kollisionen drin, da immer nur die letzten 4 Byte zählen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.932 Beiträge
 
Delphi 12 Athens
 
#17

AW: Optimaler Hash-Algorithmus und Strategie für Dateivergleiche, Verzeichnisbaum

  Alt 4. Mai 2024, 13:27
Einen Baum halte ich für überflüssig. Mir erschließt sich nicht, wofür er nützlich sein sollte, außer für die Anzeige der Daten.
Das ist für mich nützlich um die Dateien ähnlich einer Explorer-Funktion zu verwalten um Dateien hin- und her zu kopieren/verschieben/löschen/hinzufügen, falls nötig.
Dazu wollte ich eine Struktur, die in der Lage ist das lokale und das remote Verzeichnis gleichermaßen abzubilden,
um dies anzuzeigen und schnell abzugleichen und zu bearbeiten.

Eigentlich sollte das schon sehr im Sinne eines FTP-Clients, oder TotalCommander oder ähnlich aussehen.

Nur das meine App eben noch spezielle Operationen mit den Dateien machen muss, was ein FTP-Client nicht kann.

Weil das aber eigentlich eine recht generelle Aufgabenstellung ist, so denke ich zumindest, wäre es doch sehr wahrscheinlich dass es dafür bereits ein existierendes, optimales Pattern oder vielleicht eine fertige Lösung gibt.
Die Abbildung eines solchen Verzeichnissystems (Baum) zur synchronisierung ist doch prinzipiell auf allen OS, FAT/NTFS/APFS-Systemen und so weiter gleich, der einzige Unterschied sind Details wie Pfad-Delimiter, Zugriffsrechte, oder ähnlich.
Das sollte man doch perfekt plattformübergreifend abbilden und verwalten können mit einer Klasse, zumindest meiner Meinung nach.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.434 Beiträge
 
Delphi 7 Professional
 
#18

AW: Optimaler Hash-Algorithmus und Strategie für Dateivergleiche, Verzeichnisbaum

  Alt 4. Mai 2024, 19:55
Ok, ich fange an zu verstehen worauf Du hinaus möchtest und in meinem Kopf fängt ein Bild für die von Dir gewünschte Anwendung an zu entstehen. Aber wie ich das sinnvoll und anwenderfreundlich umsetzen sollte, keine Ahnung. Aber da ich heute schon ein paarmal diverse KIs "gequält" habe, dachte ich mir, versuchen wir es nochmal, aber ehrlich gesagt hab' ich keine Ahnung, ob das Ergebnis für Dich brauchbare Ideen oder umsetzbare Lösungsansätze enthält.

Die bisher von mir umgesetzen Dublettenprüfungen resultieren letztlich immer in einer Ja/Nein-Entscheidung, bei der dann nur noch entschieden werden muss, welche der Dubletten gelöscht werden soll.

Deine Aufgabenstellung dürfte weit darüber hinausgehen.

Der von der KI genannten Komponenten von JAM-Software scheinen nur für die VCL zur Verfügung zu stehen. Für mobile Apps also unbrauchbar.

Unterhaltung mit der Ki meiner Wahl:
Zitat von Frage:
Wie kann ich in Delphi eine große Verzeichnisstruktur mit ca. 100000 bis 1000000 Dateien sinnvol in einer Baumstruktur darstellen? Wie sollte meine Verwaltungsstruktur im Delphiquelltext aussehen? Sollte ich Datenhaltung und Anzeige strikt trennen oder gibt es für Delphi bereits (ggfls. auch kostenpflichtige) Komponenten, die mir hier die Arbeit erleichtern könnten. Zusätzlich zu den im Filesystem enthaltenen Daten, sollen je Datei ggfls. auch Hashwerte, wie z. B. ein MD5-Hash, und weitere Informationen für eine Dublettenerkennung, ... mit verwaltet werden. Gibt es für diese Aufgabenstellung bereits fertige Hilfmittel oder Bibliotheken?
Zitat von Antwort:
In Delphi gibt es verschiedene Ansätze, um eine große Verzeichnisstruktur mit vielen Dateien in einer Baumstruktur darzustellen. Hier sind einige Überlegungen und Empfehlungen:

1. **Verwaltungsstruktur im Quelltext:**
- Trennen Sie die Datenhaltung (Model) von der Anzeige (View) und der Steuerung (Controller). Dies folgt dem **MVC (Model-View-Controller)**-Muster.
- Erstellen Sie separate Units (Dateien) für die Datenverwaltung (z. B. eine Klasse, die die Verzeichnisstruktur repräsentiert) und die Anzeige (z. B. eine Komponente zur Darstellung des Baums).
- Verwenden Sie die **Uses-Klausel**, um die Units zu verknüpfen und auf die benötigten Klassen zuzugreifen.

2. **Baumstruktur darstellen:**
- Verwenden Sie eine **TreeView**-Komponente, um die Verzeichnisstruktur anzuzeigen. Diese Komponente bietet eine hierarchische Darstellung.
- Füllen Sie die TreeView mit den Verzeichnissen und Dateien aus Ihrem Dateisystem. Sie können rekursiv durch die Verzeichnisse gehen und die Struktur aufbauen.
- Jeder Knoten im Baum kann ein Verzeichnis oder eine Datei repräsentieren. Sie können benutzerdefinierte Daten (z. B. Hashwerte) im Tag-Eigenschaft des Knotens speichern.

3. **Drittentwicklerkomponenten:**
- Es gibt einige **kostenpflichtige und kostenlose** Komponentenbibliotheken für Delphi, die die Arbeit erleichtern können.
- **Virtual Treeview**: Eine leistungsstarke TreeView-Komponente mit vielen Funktionen und Anpassungsmöglichkeiten.
- **DevExpress TreeList**: Eine kommerzielle Komponente mit erweiterten Funktionen für die Baumdarstellung.
- **TMS Software TreeView**: Eine weitere kommerzielle Komponente mit flexiblen Optionen.

4. **Dublettenerkennung und Hashwerte:**
- Wenn Sie zusätzliche Informationen wie MD5-Hashes und Dublettenerkennung speichern möchten, können Sie benutzerdefinierte Klassen oder Records erstellen, um diese Daten zu verwalten.
- Verwenden Sie **Hash-Algorithmen** (z. B. MD5, SHA-256), um die Hashwerte für Dateien zu berechnen.
- Speichern Sie die Hashwerte und andere Metadaten in Ihrer Datenstruktur (z. B. im Tag-Eigenschaft des TreeView-Knotens).

Denken Sie daran, dass die Wahl der Komponenten und die Strukturierung des Quelltexts von Ihren spezifischen Anforderungen abhängen. Experimentieren Sie mit verschiedenen Ansätzen und wählen Sie diejenigen aus, die am besten zu Ihrem Projekt passen¹². Viel Erfolg bei Ihrer Implementierung! ??

Quelle: Unterhaltung mit Bing, 4.5.2024
(1) Project directory structure with 3rd party components. https://stackoverflow.com/questions/...rty-components.
(2) Programs and Units (Delphi) - RAD Studio. https://docwiki.embarcadero.com/RADS...s_%28Delphi%29.
(3) Improve the Structure Panel? - Delphi-PRAXiS [en]. https://en.delphipraxis.net/topic/25...ructure-panel/.
Zitat von Frage:
Gibt es bereits (erweiterbare) Komponenten für Delphi, die in der Baumstruktur auch noch die Funktionalitäten des Explorers, des Totalkommanders, ... enthalten? Es wird letztlich eine Lösung gesucht, mit der die Datei- und Verzeichnisfunktionalitäten der Baumstruktur des Explorers abgebildet wird, wobei die Möglichkeit der Erweiterung um eigene Funktionalitäten zwingend erforderlich ist.
Zitat von Antwort:
Ja, es gibt Komponenten für Delphi, die eine Baumstruktur mit Funktionalitäten ähnlich denen des Windows Explorers bieten. Hier sind einige Optionen:

1. **TJamShellTree von JAM Software**:
- Der **TJamShellTree** ist eine VCL-Komponente, die das Dateisystem von Windows in einem Baumansichtsfeld darstellt.
- Er sieht und verhält sich ähnlich wie der Ordnerbaum im linken Bereich des Windows Explorers.
- Mit dieser Delphi-Komponente können Sie den Explorer klonen oder Shell-Baumfunktionalitäten in Ihren eigenen Apps implementieren².

2. **comShellTreeView / comPidl**:
- Dies ist eine spezielle TreeView-Komponente, die sich wie der Windows Explorer verhält.
- Sie bietet eine vollständige Explorer-ähnliche Baumansicht, ermöglicht die Auswahl von Spezialordnerstandorten als Wurzel und zeigt Shell-Namen und -Symbole im TreeView an³.

3. **TListView mit vsReport-Stil**:
- Die Standard-Delphi-Komponente **TListView** unterstützt verschiedene Ansichten, darunter vsReport (ähnlich wie die Detailansicht im Explorer).
- Sie können benannte Spalten hinzufügen, um die Headerzeile zu erstellen und die gewünschten Informationen anzuzeigen.
- Die Funktionalität des Explorers (Menüs, Adressleiste, linke Leiste usw.) müssten Sie jedoch selbst hinzufügen¹.

Bitte beachten Sie, dass Sie je nach Ihren spezifischen Anforderungen die passende Komponente auswählen sollten. Die genannten Komponenten bieten verschiedene Grade an Funktionalität und Anpassungsmöglichkeiten. Viel Erfolg bei Ihrer Implementierung!

Quelle: Unterhaltung mit Bing, 4.5.2024
(1) Create ShellTree - Emulate Explorer | JAM Software. https://www.jam-software.de/shellbro...ell-tree.shtml.
(2) Explorer like treeview / comShellTreeView / comPidl - delphi. http://www.delphigroups.info/2/1e/137472.html.
(3) Windows Explorer like controls in Delphi - Stack Overflow. https://stackoverflow.com/questions/...rols-in-delphi.
(4) Emulate Explorer | JAM Software. https://www.jam-software.com/shellbr...ell-tree.shtml.
Zitat von Frage:
Können Sie mir ein Beispiel mit TJamShellTree geben?
Zitat von Antwort:
Natürlich! Hier ist ein einfaches Beispiel, wie Sie den **TJamShellTree** in Delphi verwenden können:

1. **Schritt 1: Komponente hinzufügen**
- Fügen Sie die **TJamShellTree**-Komponente zu Ihrem Formular hinzu. Sie finden diese Komponente in der Registerkarte "JamShell" im Komponenten-Palette-Fenster.

2. **Schritt 2: Ereignisse behandeln**
- Der **TJamShellTree** bietet verschiedene Ereignisse, die Sie behandeln können. Einige wichtige Ereignisse sind:
- 'OnShellChange': Wird ausgelöst, wenn sich der aktuelle Ordner ändert.
- 'OnDblClick': Wird ausgelöst, wenn der Benutzer auf einen Ordner oder eine Datei doppelklickt.
- 'OnGetImageIndex': Hier können Sie das Bildindex für jeden Knoten festlegen (z. B. Ordner- oder Dateisymbole).

3. **Schritt 3: Codebeispiel**
Delphi-Quellcode:
   procedure TForm1.FormCreate(Sender: TObject);
   begin
     // Initialisieren Sie den TJamShellTree
     JamShellTree1.Root := 'C:\'; // Wählen Sie den Startordner aus

     // Ereignisse behandeln
     JamShellTree1.OnDblClick := JamShellTree1DblClick;
     JamShellTree1.OnShellChange := JamShellTree1ShellChange;
     JamShellTree1.OnGetImageIndex := JamShellTree1GetImageIndex;
   end;

   procedure TForm1.JamShellTree1DblClick(Sender: TObject);
   begin
     // Hier können Sie auf den Doppelklick auf einen Ordner oder eine Datei reagieren
     ShowMessage('Doppelklick auf: ' + JamShellTree1.SelectedPath);
   end;

   procedure TForm1.JamShellTree1ShellChange(Sender: TObject);
   begin
     // Hier können Sie auf Änderungen im aktuellen Ordner reagieren
   end;

   procedure TForm1.JamShellTree1GetImageIndex(Sender: TObject; Node: TTreeNode);
   begin
     // Hier können Sie den Bildindex für jeden Knoten festlegen
     // Beispiel: Node.ImageIndex := 0; // Ordnersymbol
   end;
Zitat von Fortsetzung der Antwort:
4. **Schritt 4: Weitere Anpassungen**
- Passen Sie die Eigenschaften des **TJamShellTree** an, um das Verhalten und das Aussehen anzupassen.
- Sie können auch eigene Funktionen hinzufügen, um zusätzliche Funktionalitäten zu implementieren.

Denken Sie daran, die Dokumentation zu **TJamShellTree** zu konsultieren, um weitere Details und Optionen zu erfahren. Viel Erfolg bei Ihrer Implementierung!
Zitat von Frage:
Können Sie mir noch mehr Tipps zur Anpassung geben?
Zitat von Antwort:
Natürlich! Hier sind einige zusätzliche Tipps zur Anpassung des **TJamShellTree** in Delphi:

1. **Benutzerdefinierte Symbole und Bilder:**
- Sie können benutzerdefinierte Symbole oder Bilder für Ordner und Dateien verwenden.
- Verwenden Sie die Ereignisse 'OnGetImageIndex' oder 'OnGetSelectedIndex', um den Bildindex für jeden Knoten festzulegen.
- Laden Sie Ihre eigenen Symbole oder Bilder und weisen Sie sie den entsprechenden Knoten zu.

2. **Kontextmenüs hinzufügen:**
- Fügen Sie Kontextmenüs für Ordner und Dateien hinzu, ähnlich wie im Windows Explorer.
- Verwenden Sie das Ereignis 'OnContextPopup', um das Kontextmenü anzuzeigen und auf Benutzeraktionen zu reagieren.

3. **Drag & Drop-Funktionalität:**
- Implementieren Sie Drag & Drop, um Dateien und Ordner innerhalb des Baums zu verschieben.
- Verwenden Sie die Ereignisse 'OnDragOver' und 'OnDragDrop', um das Verhalten zu steuern.

4. **Filter und Suche:**
- Fügen Sie Filter hinzu, um bestimmte Dateitypen anzuzeigen oder auszublenden.
- Implementieren Sie eine Suchfunktion, um Dateien und Ordner basierend auf Benutzereingaben zu filtern.

5. **Erweiterbare Knoten:**
- Wenn Sie benutzerdefinierte Funktionalitäten hinzufügen möchten, können Sie erweiterbare Knoten verwenden.
- Erstellen Sie benutzerdefinierte Klassen oder Records, um zusätzliche Informationen für jeden Knoten zu speichern (z. B. Hashwerte, Metadaten).

6. **Spezialordner und virtuelle Knoten:**
- Der **TJamShellTree** kann auch spezielle Ordner wie "Desktop", "Eigene Dateien" usw. anzeigen.
- Verwenden Sie virtuelle Knoten, um benutzerdefinierte Daten ohne tatsächliche Dateien oder Ordner darzustellen.

Hier ist ein Beispiel, wie Sie benutzerdefinierte Symbole und Kontextmenüs hinzufügen können:
Delphi-Quellcode:
procedure TForm1.JamShellTree1GetImageIndex(Sender: TObject; Node: TTreeNode);
begin
  // Benutzerdefinierte Symbole festlegen
  if Node.Text = 'MeinOrdnerthen
    Node.ImageIndex := 1 // Index des benutzerdefinierten Ordnersymbols
  else
    Node.ImageIndex := 0; // Standard-Ordnersymbol
end;

procedure TForm1.JamShellTree1ContextPopup(Sender: TObject; MousePos: TPoint;
  var Handled: Boolean);
begin
  // Benutzerdefiniertes Kontextmenü hinzufügen
  if JamShellTree1.Selected <> nil then
  begin
    // Hier können Sie Ihr Kontextmenü erstellen und Aktionen hinzufügen
    // Beispiel: ShowMessage('Kontextmenü für ' + JamShellTree1.Selected.Text);
  end;
end;
Zitat von Fortsetzung der Antwort:
Passen Sie diese Tipps an Ihre spezifischen Anforderungen an, um eine leistungsstarke und anpassbare Baumstruktur in Ihrer Delphi-Anwendung zu erstellen. Viel Erfolg!
Zitat von Frage:
Können Sie mir noch mehr Beispiele geben?
Zitat von Antwort:
Natürlich! Hier sind einige weitere Beispiele zur Anpassung des **TJamShellTree** in Delphi:

1. **Benutzerdefinierte Symbole und Bilder:**
- Sie können benutzerdefinierte Symbole oder Bilder für Ordner und Dateien verwenden.
- Verwenden Sie die Ereignisse 'OnGetImageIndex' oder 'OnGetSelectedIndex', um den Bildindex für jeden Knoten festzulegen.
- Laden Sie Ihre eigenen Symbole oder Bilder und weisen Sie sie den entsprechenden Knoten zu.

2. **Kontextmenüs hinzufügen:**
- Fügen Sie Kontextmenüs für Ordner und Dateien hinzu, ähnlich wie im Windows Explorer.
- Verwenden Sie das Ereignis 'OnContextPopup', um das Kontextmenü anzuzeigen und auf Benutzeraktionen zu reagieren.

3. **Drag & Drop-Funktionalität:**
- Implementieren Sie Drag & Drop, um Dateien und Ordner innerhalb des Baums zu verschieben.
- Verwenden Sie die Ereignisse 'OnDragOver' und 'OnDragDrop', um das Verhalten zu steuern.

4. **Filter und Suche:**
- Fügen Sie Filter hinzu, um bestimmte Dateitypen anzuzeigen oder auszublenden.
- Implementieren Sie eine Suchfunktion, um Dateien und Ordner basierend auf Benutzereingaben zu filtern.

5. **Erweiterbare Knoten:**
- Wenn Sie benutzerdefinierte Funktionalitäten hinzufügen möchten, können Sie erweiterbare Knoten verwenden.
- Erstellen Sie benutzerdefinierte Klassen oder Records, um zusätzliche Informationen für jeden Knoten zu speichern (z. B. Hashwerte, Metadaten).

6. **Spezialordner und virtuelle Knoten:**
- Der **TJamShellTree** kann auch spezielle Ordner wie "Desktop", "Eigene Dateien" usw. anzeigen.
- Verwenden Sie virtuelle Knoten, um benutzerdefinierte Daten ohne tatsächliche Dateien oder Ordner darzustellen.

Hier ist ein Beispiel, wie Sie benutzerdefinierte Symbole und Kontextmenüs hinzufügen können:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  // Initialisieren Sie den TJamShellTree
  JamShellTree1.Root := 'C:\'; // Wählen Sie den Startordner aus

  // Ereignisse behandeln
  JamShellTree1.OnDblClick := JamShellTree1DblClick;
  JamShellTree1.OnShellChange := JamShellTree1ShellChange;
  JamShellTree1.OnGetImageIndex := JamShellTree1GetImageIndex;
  JamShellTree1.OnContextPopup := JamShellTree1ContextPopup;
end;

procedure TForm1.JamShellTree1DblClick(Sender: TObject);
begin
  // Hier können Sie auf den Doppelklick auf einen Ordner oder eine Datei reagieren
  ShowMessage('Doppelklick auf: ' + JamShellTree1.SelectedPath);
end;

procedure TForm1.JamShellTree1ShellChange(Sender: TObject);
begin
  // Hier können Sie auf Änderungen im aktuellen Ordner reagieren
end;

procedure TForm1.JamShellTree1GetImageIndex(Sender: TObject; Node: TTreeNode);
begin
  // Benutzerdefinierte Symbole festlegen
  if Node.Text = 'MeinOrdnerthen
    Node.ImageIndex := 1 // Index des benutzerdefinierten Ordnersymbols
  else
    Node.ImageIndex := 0; // Standard-Ordnersymbol
end;

procedure TForm1.JamShellTree1ContextPopup(Sender: TObject; MousePos: TPoint;
  var Handled: Boolean);
begin
  // Benutzerdefiniertes Kontextmenü hinzufügen
  if JamShellTree1.Selected <> nil then
  begin
    // Hier können Sie Ihr Kontextmenü erstellen und Aktionen hinzufügen
    // Beispiel: ShowMessage('Kontextmenü für ' + JamShellTree1.Selected.Text);
  end;
end;
Zitat von Fortsetzung der Antwort:
Passen Sie diese Tipps an Ihre spezifischen Anforderungen an, um eine leistungsstarke und anpassbare Baumstruktur in Ihrer Delphi-Anwendung zu erstellen. Viel Erfolg!
Irgendwie bin ich damit nicht zufrieden, daher noch ein Versuch die KI zu einer verwertbaren Antwort zu überreden
Zitat von Frage:
Gibt es Pattern (für die Implementierung mit Delphi), mit dessen Hilfe eine Struktur, wie sie im Verzeichnisbaum von Datenträgern üblich ist, abgebildet werden kann?
Zitat von Antwort:
Ja, es gibt ein Design-Pattern, das sich gut für die Abbildung von Baumstrukturen eignet, wie sie in Verzeichnisbäumen von Datenträgern üblich sind. Es heißt das **Composite Pattern**.

Das Composite Pattern ist ein strukturelles Design-Pattern, das dazu dient, Objekte zu einer Baumstruktur zu organisieren, um eine Hierarchie darzustellen. Es ist besonders nützlich, wenn Sie eine Gruppe von Objekten genauso behandeln möchten wie ein einzelnes Objekt.

Hier ist ein einfaches Beispiel für die Implementierung des Composite Patterns in Delphi:
Delphi-Quellcode:
type
  TComponent = class
  public
    procedure Add(Component: TComponent); virtual; abstract;
    procedure Remove(Component: TComponent); virtual; abstract;
    procedure Display(depth: integer); virtual; abstract;
  end;

  TComposite = class(TComponent)
  private
    children: TList;
    name: string;
  public
    constructor Create(n: string);
    procedure Add(Component: TComponent); override;
    procedure Remove(Component: TComponent); override;
    procedure Display(depth: integer); override;
  end;

  TLeaf = class(TComponent)
  private
    name: string;
  public
    constructor Create(n: string);
    procedure Add(Component: TComponent); override;
    procedure Remove(Component: TComponent); override;
    procedure Display(depth: integer); override;
  end;
Zitat von Fortsetzung der Antwort:
Bitte beachten Sie, dass Sie die Methoden 'Add', 'Remove' und 'Display' entsprechend Ihrer Anforderungen implementieren müssen. Dieses Beispiel dient nur zur Veranschaulichung des allgemeinen Konzepts des Composite Patterns. Es kann sein, dass Sie es für Ihre speziellen Anforderungen anpassen müssen.

Es ist auch wichtig zu beachten, dass das Composite Pattern nicht die einzige Möglichkeit ist, eine Baumstruktur zu implementieren. Abhängig von Ihren spezifischen Anforderungen könnten auch andere Ansätze oder Patterns geeignet sein. Es ist immer eine gute Idee, verschiedene Optionen zu prüfen und diejenige auszuwählen, die am besten zu Ihren Anforderungen passt.
Zitat von Frage:
Können Sie ein Beispiel für die Verwendung des Composite-Patterns geben?
Zitat von Antwort:
Natürlich, hier ist ein einfaches Beispiel für die Verwendung des Composite-Patterns in Delphi. In diesem Beispiel stellen wir eine Dateistruktur dar, in der ein Ordner mehrere Dateien oder Unterordner enthalten kann:
Delphi-Quellcode:
type
  TComponent = class
  public
    procedure Add(Component: TComponent); virtual; abstract;
    procedure Remove(Component: TComponent); virtual; abstract;
    procedure Display(depth: integer); virtual; abstract;
  end;

  TComposite = class(TComponent)
  private
    children: TList;
    name: string;
  public
    constructor Create(n: string);
    procedure Add(Component: TComponent); override;
    procedure Remove(Component: TComponent); override;
    procedure Display(depth: integer); override;
  end;

  TLeaf = class(TComponent)
  private
    name: string;
  public
    constructor Create(n: string);
    procedure Add(Component: TComponent); override;
    procedure Remove(Component: TComponent); override;
    procedure Display(depth: integer); override;
  end;

implementation

constructor TComposite.Create(n: string);
begin
  name := n;
  children := TList.Create;
end;

procedure TComposite.Add(Component: TComponent);
begin
  children.Add(Component);
end;

procedure TComposite.Remove(Component: TComponent);
begin
  children.Remove(Component);
end;

procedure TComposite.Display(depth: integer);
var
  i: integer;
begin
  writeln(StringOfChar('-', depth) + name);

  for i := 0 to children.Count - 1 do
    TComponent(children[i]).Display(depth + 2);
end;

constructor TLeaf.Create(n: string);
begin
  name := n;
end;

procedure TLeaf.Add(Component: TComponent);
begin
  writeln('Cannot add to a leaf');
end;

procedure TLeaf.Remove(Component: TComponent);
begin
  writeln('Cannot remove from a leaf');
end;

procedure TLeaf.Display(depth: integer);
begin
  writeln(StringOfChar('-', depth) + name);
end;
Zitat von Fortsetzung der Antwort:
In diesem Beispiel repräsentiert 'TComposite' einen Ordner und 'TLeaf' eine Datei. Ein Ordner ('TComposite') kann mehrere Dateien oder Unterordner ('TLeaf' oder 'TComposite') enthalten, während eine Datei ('TLeaf') keine weiteren Dateien oder Ordner enthalten kann.

Bitte beachten Sie, dass Sie die Methoden 'Add', 'Remove' und 'Display' entsprechend Ihrer Anforderungen implementieren müssen. Dieses Beispiel dient nur zur Veranschaulichung des allgemeinen Konzepts des Composite Patterns. Es kann sein, dass Sie es für Ihre speziellen Anforderungen anpassen müssen.

Es ist auch wichtig zu beachten, dass das Composite Pattern nicht die einzige Möglichkeit ist, eine Baumstruktur zu implementieren. Abhängig von Ihren spezifischen Anforderungen könnten auch andere Ansätze oder Patterns geeignet sein. Es ist immer eine gute Idee, verschiedene Optionen zu prüfen und diejenige auszuwählen, die am besten zu Ihren Anforderungen passt.
Zitat von Frage:
Wie kann ich das Composite Pattern in meiner eigenen Anwendung verwenden?
Zitat von Antwort:
Die Verwendung des Composite-Patterns in Ihrer eigenen Anwendung hängt stark von den spezifischen Anforderungen Ihrer Anwendung ab. Hier sind jedoch einige allgemeine Schritte, die Sie befolgen können:

1. **Identifizieren Sie die Komponenten**: Zuerst müssen Sie die Komponenten Ihrer Anwendung identifizieren, die in einer Baumstruktur organisiert werden können. In unserem vorherigen Beispiel waren dies Dateien und Ordner.

2. **Implementieren Sie die Komponentenklasse**: Implementieren Sie eine abstrakte Klasse (in Delphi eine Klasse mit abstrakten Methoden), die als Oberklasse für alle Komponenten dient. Diese Klasse sollte Methoden für das Hinzufügen, Entfernen und Anzeigen von Komponenten enthalten.

3. **Implementieren Sie die Blatt- und Composite-Klassen**: Implementieren Sie dann die spezifischen "Blatt"- und "Composite"-Klassen, die von der Komponentenklasse erben. Die Blattklasse repräsentiert die Endpunkte der Baumstruktur (z.B. Dateien), während die Composite-Klasse die nicht-Endpunkte repräsentiert (z.B. Ordner).

4. **Verwenden Sie die Klassen in Ihrer Anwendung**: Schließlich können Sie diese Klassen in Ihrer Anwendung verwenden, um eine Baumstruktur zu erstellen und zu manipulieren. Sie können neue Komponenten hinzufügen, bestehende Komponenten entfernen und die Struktur anzeigen, indem Sie die entsprechenden Methoden aufrufen.

Bitte beachten Sie, dass dies nur ein allgemeiner Leitfaden ist und Sie möglicherweise Anpassungen vornehmen müssen, um das Composite-Pattern an die spezifischen Anforderungen Ihrer Anwendung anzupassen. Es ist auch wichtig zu beachten, dass das Composite-Pattern nicht immer die beste Lösung ist, und es kann andere Design-Patterns oder Ansätze geben, die besser zu Ihren Anforderungen passen. Es ist immer eine gute Idee, verschiedene Optionen zu prüfen und diejenige auszuwählen, die am besten zu Ihren Anforderungen passt.
Hoffentlich ist für Dich da jetzt etwas brauchbares oder zumindest ein Ansatz für eine Lösungsmöglichkeit enthalten.
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.932 Beiträge
 
Delphi 12 Athens
 
#19

AW: Optimaler Hash-Algorithmus und Strategie für Dateivergleiche, Verzeichnisbaum

  Alt 6. Mai 2024, 07:50
Danke sehr für die Mühe.
Ich habe mal ein bischen darüber nachgedacht wellche Pattern in Frage kämen und habe hier ein grobes Konzept, was hoffentlich das was ich möchte gut abbildet.
Die spezifischen Adapter erzeugen die Hashes systemabhängig und geben diese an den zentralen Controller weiter.

Delphi-Quellcode:
program PathManagement;

{$APPTYPE CONSOLE}

uses
  System.SysUtils, System.Generics.Collections;

type
  IPathInterface = interface
    function GetFormattedPath: string;
  end;

  TPathController = class
  private
    FAdapters: TList<IPathInterface>;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Attach(Adapter: IPathInterface);
    procedure NotifyAdapters;
  end;

  TPathAdapter = class(TInterfacedObject, IPathInterface)
  protected
    FController: TPathController;
    FPath: string; // Jeder Adapter verwaltet nun seinen eigenen Pfad
  public
    constructor Create(Controller: TPathController; const Path: string);
    function GetFormattedPath: string; virtual; abstract;
  end;

  TPathAdapter_Windows = class(TPathAdapter)
  public
    function GetFormattedPath: string; override;
  end;

  TPathAdapter_Unix = class(TPathAdapter)
  public
    function GetFormattedPath: string; override;
  end;

{ TPathController Implementation }
constructor TPathController.Create;
begin
  inherited Create;
  FAdapters := TList<IPathInterface>.Create;
end;

destructor TPathController.Destroy;
begin
  FAdapters.Free;
  inherited Destroy;
end;

procedure TPathController.Attach(Adapter: IPathInterface);
begin
  FAdapters.Add(Adapter);
end;

procedure TPathController.NotifyAdapters;
var
  Adapter: IPathInterface;
begin
  for Adapter in FAdapters do
    WriteLn(Adapter.GetFormattedPath);
end;

{ TPathAdapter Implementation }
constructor TPathAdapter.Create(Controller: TPathController; const Path: string);
begin
  inherited Create;
  FController := Controller;
  FPath := Path;
  FController.Attach(Self);
end;

{ TPathAdapter_Windows Implementation }
function TPathAdapter_Windows.GetFormattedPath: string;
begin
  //! Nur als Beispiel womrum es geht, genau solche unnötigen Umkopierungen möchte ich durch Baum-Auflösung im PathController Vermeiden
  Result := StringReplace(FPath, '/', '\', [rfReplaceAll]);
end;

{ TPathAdapter_Unix Implementation }
function TPathAdapter_Unix.GetFormattedPath: string;
begin
  //! Nur als Beispiel womrum es geht, genau solche unnötigen Umkopierungen möchte ich durch Baum-Auflösung im PathController Vermeiden
  Result := StringReplace(FPath, '\', '/', [rfReplaceAll]);
end;

var
  Controller: TPathController;
  WinAdapter, UnixAdapter: IPathInterface;
begin
  try
    Controller := TPathController.Create;
    WinAdapter := TPathAdapter_Windows.Create(Controller, 'C:\Users\Example\LocalDocuments'); // hier hinter sollten sich die identischen Dokumente befinden
    UnixAdapter := TPathAdapter_Unix.Create(Controller, 'FTP://mytest.com/remote/Documents'); //

    Controller.NotifyAdapters; // Kann verschiedene Lokations-übergreifende Aktionen anstossen

    ReadLn;
  finally
    Controller.Free;
  end;
end.
Alle Funktionalität um die verschiedenen Lokationen abzubilden, synchron zu halten bzw. separat zu bearbeiten wäre zentral in dem PathController gekapselt.
Alle Zugriffe, aus Sicht einer einzelnen Lokation wären in den PathAdaptern und deren PathInterface gekapselt.

Damit komme ich glaube ich weiter.
Ich werde zuerst mal versuchen in dem PathControll mit einem TFdMemTable zu arbeiten, wenn das nicht reicht, dann kann ich immer noch auf Bäume und sonstiges umsteigen.

Vielen Dank erstmal an alle.

Geändert von Rollo62 ( 6. Mai 2024 um 12:22 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.012 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#20

AW: Optimaler Hash-Algorithmus und Strategie für Dateivergleiche, Verzeichnisbaum

  Alt 6. Mai 2024, 11:41
Ich möchte deine Aufmerksamkeit auf xxHash richten, das ich mittlerweile statt MD5 verwende. Die Seite von Cyan4973 auf Github ist interessant, ich habe den Wrapper von YWtheGod (auch auf Github) genommen.
FWIW xxh32 gibt's auch als native Implementierung in Spring4D (natürlich für Windows in asm implementiert, somit durchaus vergleichbare Performance).
Ist seit 2.0 die Standard Hashfunktion für Dictionary und Co
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie ( 6. Mai 2024 um 11:45 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 11:16 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz