Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller Suche (https://www.delphipraxis.net/185758-konzeptfrage-datenhaltung-vieler-datei-infos-und-deren-darstellg-mit-schneller-suche.html)

juergen 4. Jul 2015 16:27

Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller Suche
 
Hallo zusammen,
dieser Thread ist aus diesem entstandehttp://www.delphipraxis.net/1307584-post1.htmln:

Da ich nun motiviert bin ein altes Programm neu hochzuziehen, möchte ich jetzt auch "auf das richtige Pferd" setzen.:)

Voraussetzungen: Delphi XE, ich habe das Quantumgrid und für DB-Zugriffe den Vorgänger vom FireDAC (AnyDAC).
Da ich diese Komponenten schon etwas kenne, würde ich diese auch am liebsten nutzen wollen, den VT eher nicht (momentan zu kompliziert für mich, da ich noch nie damit gearbeitet habe).

Mein momentan überlegtes Konzept:
Welche Daten benötige ich überhaupt? => Dateipfad, Dateiname, Änderungsdatum, evtl. Erstelldatum, Dateigröße. Weiterhin in einem separaten Thread einige MP3- und Exif-Infos auslesen.
Mein momentaner Plan: Ich sauge mir das Ganze in eine SQLite-DB!??? Mehrplatzfähigkeit wird nicht benötigt.

Was wichtig ist:
Performante Datei-Suche. Es gilt oft ca. 500.000 Datensätze nach Dateinamen zu durchsuchen und zu filtern. Das Ganze muss unter 1 s ablaufen.
Da weiß ich nicht ob die o.g. Komponenten das überhaupt her geben.
Weiterhin ist wichtig, dass das Ganze in irgendeiner Form abgespeichert werden kann. Das Programm soll beim Neustart alle zuvor eingelesen Datei-Infos anzeigen und nicht neu einlesen müssen.

Meine Fragen:
1. Welche Erfahrungen habt ihr in diesem Bereich und welche Empfehlungen resultiert daraus?
2. Welches Konzept würdet Ihr anwenden? Datenhaltung= DB?, Anzeige= Quantumgrid?
3. Ist eine Datenbank das Mittel der Wahl? (performant genug?) Evtl. TObjectList?
4. Verwendung welcher Komponenten?

Vielen Dank schon mal vorab!

idefix2 4. Jul 2015 16:53

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Aus deinem Beitrag ist mir nicht wirklich klar geworden, was du überhaupt genau machen willst.

Popov 4. Jul 2015 17:09

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Ich weiß zwar auch nicht was du speicherst (liest sich nach Daten, MP3, usw.). Wenn ich die Dateninformationen eines Verzeichnisses einlese, dann speichere ich alle Informationen zu einer Datei einfach als TSearchRec. Einfache geht es nicht und alle Daten sind später bei Hand.

TSearchRec in DB ablegen ist allerdings schwieriger. Trotzdem würde ich alles sichern.

juergen 4. Jul 2015 17:47

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
sorry, wenn ich mich nicht richtig ausgedrückt habe...
Ich lese die Dateiinformationen erst einmal über TSearchRec.... ein.Danach die MP3- und Exif-Infos.
Die Frage ist in erster Linie wo ich die relativ große Menge der Dateiinformationen speichere (DB,TObjectList ????), so das auch eine Suche sehr schnell ist. Weiterhin was ich zur Darstellung der reinen Dateinamen verwende (Quantumgrid, ...???), bzw. alternative Konzepte

DeddyH 4. Jul 2015 17:57

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Ich denke, eine Datenbank kann nicht verkehrt sein. Wenn man dann noch entsprechende Indizes anlegt, sollte auch die Performance zufriedenstellend sein. Wie man die Daten darstellt, ist Geschmackssache.

Popov 4. Jul 2015 18:08

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Wie ich schon oben meinte, wenn es nur Suche sein soll, also DB kein Muss ist, würde ich es in einer Liste speichern. Egal welche es am Ende auch ist, ob Array oder TObjectList. Allerdings kann ich dir aus meiner Erfahrung sagen, dass TObjectList schnell genug ist. Ich hab letztens hier irgendwo ein kleines Beispiel mit TObjectList veröffentlicht, bei dem ich 100.000 Daten in etwa 14ms sortiert habe.

Und wie gesagt, ich würde aus TSearchRec nicht nur einzelne Informationen einlesen, sondern einfach alles kopieren. TSearchRec ist nur ein Record, mehr nicht. Man hat also gleich alles bei Hand.

mm1256 4. Jul 2015 19:49

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
TSearchRec ist zum Speichern schon sehr effizient, keine Frage. Aber wenn du dann bei der Suche...
Zitat:

Es gilt oft ca. 500.000 Datensätze nach Dateinamen zu durchsuchen und zu filtern. Das Ganze muss unter 1 s ablaufen.
...die TSearchRec's wieder aufdröseln musst, gibt's die A-Karte gratis

mkinzler 4. Jul 2015 20:01

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Zitat:

Wie ich schon oben meinte, wenn es nur Suche sein soll, also DB kein Muss ist, würde ich es in einer Liste speichern. Egal welche es am Ende auch ist, ob Array oder TObjectList. Allerdings kann ich dir aus meiner Erfahrung sagen, dass TObjectList schnell genug ist.
Wenn es nur um diese Suche geht, kann man ganz auf die Speicherung in einer Liste o.ä. sparen, da man ja sowie so die Verzeichnisse durchsuchen muss. Sollen die Informationen persistent erhalten werden, muss man diese ja wieder irgendwie ablegen, wenn man nicht bei jedem Programmstart sen "index" neu anlegn lassen will. Ich würde die Infos gleich in einer datenbnk ablegen.

Dejan Vu 5. Jul 2015 10:38

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Deine Idee mit einer kleinen DB war schon mal nicht falsch bzw. der naheliegende Weg.

Erstelle Dir zunächst die Tabellenstruktur(en) zum Speichern der Daten in der DB. Das geht einher mit den Recherchemöglichkeiten, die Du deinem System spendieren möchtest.

Anschließend erzeugst Du die Queries, um deine Fragen zu beantworten.

Dann importierst Du die Daten und prüfst, ob deine Queries zum gewünschten Ergebnis in der gewünschten Zeit kommen.

Du änderst ggf. das Design so, das deine Performancevorgaben erfüllt werden.

Und zum Schluß die UI.

stahli 5. Jul 2015 11:11

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Die Ordnerstruktur ist ja letztlich auch eine Datenbank.
Unter VisualStudio kann man wohl auch per SqlServer direkt auf die Ordnerstruktur zugreifen. Genaueres kann ich dazu aber jetzt nicht sagen.

Welche Suchfunktionen Delphi in Ordnern ermöglicht, kann ich auch nicht sagen.

Eine Datenbank zu verwenden und diese zum Suchen zu verwenden ist sicher kein schlechter Weg.
Ein paar passende Indizes würde eine schnelle Suche ermöglichen.

Das Problem wird die Synchronisation sein. Wenn Du Dein Projekt startest und zum letzten Lauf hat sich etwas an in den Ordnern geändert müsste ja die Datenbank erst mal aktualisiert werden. Gleiches, wenn sich während der Laufzeit etwas in den Ordnern ändert.

Im Grunde hast Du einen redundanten Datenbestand.

Insofern wäre es vielleicht besser, die Ordner direkt nach Treffern zu durchsuchen und diese zur Anzeige in einer Liste zu sammeln.

jobo 5. Jul 2015 11:19

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Die Frage von mkinzler halte ich für durchaus wichtig.
Wie soll das Programm sich bei Änderungen im Dateisystem verhalten?
Jede Persistierung egal wie sie erfolgt entfernt sich zwangsläufig von der Realität im Dateisystem. Eine suche in den persistierten Daten findet demnach entweder Leichen oder "übersieht" Neueinträge.
Ob eine DB Persistierung den erfofften Geschwindigkeitsvorteil gegenüber einer Dateisystemsuche erbringt und der Aufwand dazu im Verhältnis steht, wäre eine Frage, die man näherungsweise mit kleinem Aufwand anhand von Testdaten prüfen könnte.

Hübsch wäre vielleicht, sich in die Änderungen des FS zu hooken und so die Persistierung on the fly synchron zu halten.

Sir Rufo 5. Jul 2015 11:57

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Man kann das Programm doch mit der Suche im Explorer vergleichen. Die indizierten Orte (Ordner) werden auch laufend überwacht (bzw. per Benachrichtigung bei einer Änderung).

Die einzige Frage ist, ob diese Indizierung permanent erfolgen soll (Dienst) oder nur wenn die Anwendung läuft.

mm1256 5. Jul 2015 12:10

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Zitat:

Zitat von jobo (Beitrag 1307713)
Die Frage von mkinzler halte ich für durchaus wichtig.
Wie soll das Programm sich bei Änderungen im Dateisystem verhalten?

Ja, das ist wichtig. Weil es wohl hier um so was ähnliches wie bei meiner privaten mp3-Verwaltung geht, schreib ich mal, wie ich das hier gelöst habe: In einer Config-Datei speichere ich beim Anlegen neuer Dateien die jeweiligen Pfade. Bei einer Aktualisierung gehe ich (mittlerweile in einem eigenen Thread) diese Pfade durch und schaue nach, ob eine Datei verändert wurde. Die Änderungen werden im Hintergrund ohne die Anzeige zu stören über eine separate TTable-Komponente in die DB geschrieben. Für die Anzeige verwende ich eine TQuery. Somit reicht ein "Refresh" der TQuery wenn die Aktualisierung fertig ist, um diese auch auf den Bildschirm zu bringen. Man bekommt also von der Aktualisierung gar nichts mit.

In der DB selber werden nur die Dateinamen gespeichert. Diese sind generell so aufgebaut: {Interpret} - {Titel}.mp3. Ein kleines Tool ermöglicht das physikalische Umbenennen vorhandener mp3-Dateien (Interpret+Titel eingeben, und dann Datei umbenennen). Das Datei-Datum wird mit dem Erscheinungsdatum oder Aufnahmedatum belegt. Die Zeit ist bei erfassten Dateien immer 00:00:00. So sieht man auch im Explorer neue/veränderte Dateien. Interpret, Titel, Datum/Zeit, Erscheinungsjahr, Land, Genre, Rhytmus und Dateiname sind indizierte Felder. Interpreten, Land, Genre und Rhytmus werden wegen einheitlicher Schreibweise über LookUp's aus entsprechenden DB's gefüllt. Somit ist die Suche und das Filtern (z.B. nur ein Interpret) von Daten sehr schnell.

Vielleicht hilft's ja?

Popov 5. Jul 2015 12:41

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Für mich ist die Frage die sich stellt die: sollen die Infos für die Nachwelt gesichert werden? Denn dafür wäre eine Datenbank durchaus geeignet. Eine Bank ist immer dann gut, wenn man etwas für eine gewisse Zeit da ablegen will, z. B. Geld auf Bank bringen oder Adressen in einer Datenbank ablegen. Oder geht es hier nur um das Einlesen von Informationen zwecks temporärer Verarbeitung?

Sir Rufo 5. Jul 2015 13:31

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
@Popov

Es geht hier rein um die Performance und die Datenbank soll als Cache herhalten.

juergen 5. Jul 2015 19:33

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Hallo zusammen,:)

einleitend zuerst mal das Anwendungsgebiet des Tools, dann wird wohl einiges klarer:
- Im geschäftl. Bereich dient es dazu jede Woche einmal ein Serverlaufwerk mit ganz vielen Dateien neu einzulesen.
Dann, z.B. während eines Kunden-Telefonats, kann ich *schnell* mit meinem Tool irgendein Dokument suchen und direkt aus der Suchvorschau öffnen. Ggf. muss ich die Suche ständig wiederholen, bis das gewünschte Dokument gefunden wurde! Mein Gegenüber wartet... Auf Grund der Datenmenge (ca. 500.000 Dateien) ist die Performance eben wichtig.
- Im privatem Bereich dient das Tool vorwiegend zum Einlesen von MP3-Dateien und Fotos, der Suche nach Liedern, wo die genaue Schreibweise nicht immer 100% bekannt ist (verschiedene Such-Algorithmen) und die Bearbeitung der Dateien (Stapelbearbeitungen zum taggen oder umbenennen...). Weiterhin kann das Ergebnis der Suchvorschau direkt an meinen Musikplayer übergeben werden um z.B. eine Playliste zu erstellen...

Die Dateiinformationen müssen *nicht* permanent neu eingelesen werden (zumindest im Moment).

Ich hatte heute nun mal begonnen mit einer SQLite-DB etwas zu experimentieren. Dazu habe ich ca. 140.000 Dateipfade+Dateinamen in eine DB mit nur einer Tabelle gepumpt. Die Tabelle hat nur 2 Felder => AutoInc (Integer) und Dateipfad (255 VarChar). Nun, ich bin erst mal ernüchtert was die Suchgeschwindigkeit angeht.
Weiterhin hatte ich zum testen mal mit SQLite Maestro-Programm gespielt. Das Suchen dauerte dort auf jeden Fall länger wie meine momentane Suche in einer TStringList! Allerdings weiß ich nicht wie die Suche dort funktioniert. Das Maestro-Programm nutzt wohl auch das Quantumgrid zur Anzeige. Ob jetzt das Grid die Daten filtert oder eine Query weiß ich nicht.
Ich habe gelesen, dass evtl. InMenory-Lösungen hierfür hilfreich wären.

Insgesamt habe ich einfach keinerlei Erfahrung in dem Bereich und daher kostet alles viel Zeit.
Da der Aufwand für mich im Moment überhaupt nicht einschätzbar ist (wer weiß was mich bei Nutzung einer DB noch alles so erwartet), werde ich wohl eher das mir fehlende Datei-Datum zusätzlich in meiner TStringList irgendwie speichern.

mkinzler 5. Jul 2015 20:01

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Nach was suchst Du? hat das Feld einen Index?

Luckie 5. Jul 2015 22:21

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Würde es nicht reichen sich zu merken wo die Datei ist und dann, wenn man sie braucht, die Infos auszulesen?

Was du jetzt vor hast klingt für mich, was Microsoft mal geplant hatte, das Dateisystem in eine DB zu überführen. Sie haben es aber nie verwirklicht.

Weil das Problem ist doch letztendlich die Datei schnell zu finden. Die Infos auslesen dauert doch wohl nur Millisekunden. Also würde ich den Dateinamen und den Speicherort in der DB ablegen und den Dateinamen indexieren. Wenn es mehrere gleichnamige Dateien gibt, kann man sie am Speicherort identifizieren.

mkinzler 5. Jul 2015 22:36

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Zitat:

Was du jetzt vor hast klingt für mich, was Microsoft mal geplant hatte, das Dateisystem in eine DB zu überführen.
Wie kommst Du darauf, er legt ja nur die Pfade ab, nicht den Inhalt.

idefix2 5. Jul 2015 22:47

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Wenn ich das richtig verstehe, geht es dir nicht um eine schnelle gezielte Dateisuche, sondern um einen rasch reagierenden Dateifilter, der aber meistens die komplette Tabelle durchsuchen muss, weil der gesuchte Namensteil nicht unbedingt am Anfang des Dateinamens steht.

In so einem Fall ist eine in-Memory Lösung wie zum Beispiel eine Stringliste sicher schneller als jede Datenbank.

Abhängig davon, wie so ein Dateifilter bei dir genau aussehen kann, sind aber sicher Optimierungen möglich, um das zu beschleunigen.

Harry Stahl 5. Jul 2015 23:20

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von idefix2 (Beitrag 1307755)
Wenn ich das richtig verstehe, geht es dir nicht um eine schnelle gezielte Dateisuche, sondern um einen rasch reagierenden Dateifilter, der aber meistens die komplette Tabelle durchsuchen muss, weil der gesuchte Namensteil nicht unbedingt am Anfang des Dateinamens steht.

In so einem Fall ist eine in-Memory Lösung wie zum Beispiel eine Stringliste sicher schneller als jede Datenbank.

Also ich habe keine Ahnung, wie lange eine typische Datenbank braucht, um ein Ergebnis zurück zu liefern. Ich haben in meinen Dateimanager-Programm bei der Suchen-Option statt tatsächlich in den "echten" Ordnern zu suchen, eine Alternative, in der Datenbank zu suchen. Die Dateien muss man zuvor einmal eingelesen haben (gerade mal getestet, auf einer SSD wird Laufwerk C:\mit 800.000 Dateien in ca. 1 Minute eingelesen).

Die Suche nach einer Datei (bzw. Filter) dauert dann ca. 2 Sekunden. Die Daten in der Datei werden in eine einfache Stringlist geladen, sind nicht sortiert, es müssen alle Einträge durchlaufen werden. Wenn man hier mit Multithreading arbeiten würde, könnte man die Suche zeitlich noch deutlich optimieren. Bei den 800.000 Dateien wird die Datendatei ca. 46 MB groß, eingelesen in der Arbeitsspeicher werden ca. 100 BM benötigt. In der Datei wird das Verzeichnis (aber nicht mehrfach) und der Dateiname, das Datum, die Größe und das Änderungsdatum erfasst.

Das Suchergebnis kann ich noch mal durch einen 2. Filter eingrenzen (siehe anliegenden Screenshot)

Luckie 5. Jul 2015 23:30

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Zitat:

Zitat von mkinzler (Beitrag 1307754)
Zitat:

Was du jetzt vor hast klingt für mich, was Microsoft mal geplant hatte, das Dateisystem in eine DB zu überführen.
Wie kommst Du darauf, er legt ja nur die Pfade ab, nicht den Inhalt.

Und die ganzen Infos: MP3 Tag, EXIF-Daten, Datum usw.

Dalai 6. Jul 2015 00:16

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Mmh, reicht da auch ein externes Tool wie Everything, Hddb oder sowas, die die MFT indexieren?

MfG Dalai

Dejan Vu 6. Jul 2015 06:53

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Wenn der TE nur nach Dateinamen suchen möchte, reichen die hier vorgestellten Verfahren.

Ansonsten würde ich ein Fulltext-System wie Lucene empfehlen oder irgend etwas anderes 'Fertiges', wie mein Vorredner schon anmerkte.

Bitte macht nicht den Fehler, für ein Standardproblem etwas eigenes zu programmieren. Außer exorbitanten Kosten gewinnt man dabei gar nichts.

Siehe auch: https://de.wikipedia.org/wiki/Not-invented-here-Syndrom

mschaefer 6. Jul 2015 08:45

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Moin zusammen,

Wir hatten mal einen Thread der sich mit der Geschwindikgeit von Listen beschäftigt hat und bei ID und Pfad-Listen fällt mir gleich Hashlist und DirectoryList ein. Schaut doch mal bei Alzaimar´s -Listen-Thread. Man kann sich aus dem Beispielprogramm eine Liste heraussuchen.

Grüße in die Runde

jobo 6. Jul 2015 11:34

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Zitat:

Zitat von juergen (Beitrag 1307661)
Was wichtig ist:
Performante Datei-Suche. Es gilt oft ca. 500.000 Datensätze nach Dateinamen zu durchsuchen und zu filtern. Das Ganze muss unter 1 s ablaufen.

Also ich hab hier ein Lazarusprogramm, das unter der Sekunde bleibt bei ca 550000 Datenätzen. Das ist aber nicht optimiert auf sowas.

juergen 6. Jul 2015 11:40

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Hallo zusammen,

ich habe nun eine -naja- Q&D-Lösung, die für mich reicht. Externe Tools bieten meines Wissens nur das durchsuchen der MFT bei lokalen Laufwerken an. Aber vor allem möchte ich mein Tool nach meinen Bedürfnissen. :)
Ich bleibe nun bei meinen 2 Stringlisten.
In der ersten TStringList werden Dateipfad+Name (und jetzt neu) das Datum gespeichert (getrennt durch 5 Doppelpunkte). Anzeigen tue ich in einer TListbox im virtullen Modus nur die Dateinamen. In einer für Textsuche angepassten weiteren StringList von alzheimer speichere ich nur die Dateinamen und im Objekt die eindeutige Nummer der "Hauptliste". Somit habe ich in meiner Suchvorschau immer den benötigten, direkten Verweis auf die Hauptliste:
Delphi-Quellcode:
ExtractFileName(copy(sl_Master[Integer(SearchForm.Listbox1.Items.Objects[i])], 1,
  pos(':::::', sl_Master[Integer(SearchForm.Listbox1.Items.Objects[i])])-1)
Die Suche bleibt immer noch so schnell, dass ich meine "Live"-Suche anwenden kann (bei jeder neuen Eingabe eines neuen Buchstaben wird neu gesucht).
MP3-und Exif-Tags lese ich erst aus, wenn die Datei in der Listbox angeklickt wird.
Da ich die Hauptliste sortiere nach Name, Verzeichnis, Dateiendung und nach Datum, benötige ich diese Infos ja in der Hauptliste. Hinzukommen wird noch die Sortierung nach Bewertung (MP3). Aber das funktioniert ja nach dem jetzigen System, indem ich einfach 6 Doppelpunkte als weiteren Trenner für die Bewertungen verwende. :oops:

Das Ganze ist für mich überschaubar, umsetzbar und nun auch erweiterbar. Ist sicherlich nicht elegant (da ich mit copy() mir immer die "Teile" aus der Hauptstringlist heraus fischen muss) und eine 2. Liste verwalten muss, aber erfüllt erstmal seinen Zweck.

Danke für eure Ideen und Ratschläge! :dp:

Sir Rufo 6. Jul 2015 13:51

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Wenn du eine ListView nimmst mit
Delphi-Quellcode:
OwnerData := True
, dann kannst du das mit einer
Delphi-Quellcode:
TObjectList<T>
sehr einfach behandeln.
Delphi-Quellcode:
type
  TDataItem = class
    property Name : string;
    property Date : TDateTime;
  end;

  TMyForm = class( TForm )
    ListView1 : TListView;
    procedure ListView1Data( Sender:TObject; Item : TListViewItem );
  private
    FAllList : TObjectList<TDataItem>;
    FHitList : TList<TDataItem>;
    procedure SetHitList( AHitList : TList<TDataItem> );
  end;

procedure TMyForm.SetDataList( AHitList : TList<TDataItem> );
begin
  // Alte Liste löschen
  if FHitList <> FAllList then
    FreeAndNil( FHitList );

  // Neue Liste setzen
  FHitList := AHitList;
  // Items.Count setzen
  if Assigned( FHitList ) then
    ListView1.Items.Count := FHitList.Count
  else
    ListView1.Items.Count := 0;
end;

procedure ListView1Data( Sender:TObject; Item : TListViewItem );
var
  LItem : TDataItem;
begin
  LItem := FHitList[Item.Index];
  Item.Caption := LItem.Name;
  Item.SubItems.Add( DateToStr( LItem.Date ) );
end;

freimatz 6. Jul 2015 14:26

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Zitat:

Zitat von juergen (Beitrag 1307785)
Ich bleibe nun bei meinen 2 Stringlisten.

„Wer als Werkzeug nur einen Hammer hat, sieht in jedem Problem einen Nagel.“
Wer als Werkzeug nur eine TStringlist kennt, für den sind alles Strings :twisted:

Sir Rufo 6. Jul 2015 15:51

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier mal so ein Minimal-Projekt im Anhang (Source + EXE) - ohne Threading, alles in einem Thread (der Start könnte etwas länger dauern)
Delphi-Quellcode:
unit Model_FileInfo;

interface

uses
  System.Generics.Collections,
  System.SysUtils;

type
  TObjectActionResult<TResult: class> = reference to procedure( AResult: TResult; AException: Exception; var ADispose: Boolean );

  TFileInfo = class
  private
    FFullName: string;
    function GetFileName: string;
    function GetPath: string;
  public
    constructor Create( const AFileName: string );
    property FullName: string read FFullName;
    property FileName: string read GetFileName;
    property Path: string read GetPath;
  end;

  TFileInfoList = class( TObjectList<TFileInfo> )
    procedure Query( APredicate: TPredicate<TFileInfo>; callback: TObjectActionResult<TFileInfoList> );
  end;

implementation

uses
  System.IOUtils;

{ TFileInfoList }

procedure TFileInfoList.Query( APredicate: TPredicate<TFileInfo>; callback: TObjectActionResult<TFileInfoList> );
var
  LItem: TFileInfo;
  LResult: TFileInfoList;
  LDispose, LDummy: Boolean;
begin
  LDispose := True;
  LResult := nil;
  try
    try

      LResult := TFileInfoList.Create( False );
      for LItem in Self do
      begin
        if APredicate( LItem ) then
          LResult.Add( LItem );
      end;

    except
      on E: Exception do
      begin
        callback( nil, E, LDummy );
        Exit;
      end;
    end;
    callback( LResult, nil, LDispose );

  finally
    if LDispose then
      LResult.Free;
  end;
end;

{ TFileInfo }

constructor TFileInfo.Create( const AFileName: string );
begin
  inherited Create;
  FFullName := AFileName;
end;

function TFileInfo.GetFileName: string;
begin
  Result := TPath.GetFileName( FFullName );
end;

function TFileInfo.GetPath: string;
begin
  Result := TPath.GetFullPath( FFullName );
end;

end.
Delphi-Quellcode:
unit Form_Main;

interface

uses
  Model_FileInfo,
  System.Diagnostics,
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class( TForm )
    ListView1: TListView;
    Edit1: TEdit;
    StatusBar1: TStatusBar;
    QueryTimer: TTimer;
    procedure ListView1Data( Sender: TObject; Item: TListItem );
    procedure Edit1Change( Sender: TObject );
    procedure QueryTimerTimer( Sender: TObject );
  private
    FQueryWatch: TStopwatch;

    FAllList: TFileInfoList;
    FHitList: TFileInfoList;
    procedure SetHitList( AHitList: TFileInfoList );
    procedure BuildAllList( );
    procedure QueryCallback( AResult: TFileInfoList; AException: Exception; var ADispose: Boolean );
    procedure QueryData( const QueryStr: string );
  public
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  System.IOUtils;

{ TForm1 }

procedure TForm1.AfterConstruction;
begin
  inherited;
  BuildAllList;
  QueryData( Edit1.Text );
end;

procedure TForm1.BeforeDestruction;
begin
  inherited;
  SetHitList( nil );
  FreeAndNil( FAllList );
end;

procedure TForm1.BuildAllList;
var
  LPath, LFileName: string;
begin
  FAllList := TFileInfoList.Create( True );

  for LPath in TArray<string>.Create(
    {} TPath.GetPublicPath,
    {} TPath.GetLibraryPath,
    {} TPath.GetDocumentsPath,
    {} TPath.GetDownloadsPath,
    {} TPath.GetPicturesPath,
    {} TPath.GetMusicPath,
    {} TPath.GetMoviesPath ) do
  begin
    for LFileName in TDirectory.GetFiles( LPath, '*.*', TSearchOption.soAllDirectories ) do
    begin
      FAllList.Add( TFileInfo.Create( LFileName ) );
    end;
  end;

end;

procedure TForm1.Edit1Change( Sender: TObject );
begin
  QueryTimer.Enabled := True;
end;

procedure TForm1.ListView1Data( Sender: TObject; Item: TListItem );
var
  LItem: TFileInfo;
begin
  LItem := FHitList[ Item.Index ];
  Item.Caption := LItem.FileName;
  Item.SubItems.Add( LItem.Path );
end;

procedure TForm1.QueryCallback( AResult: TFileInfoList; AException: Exception; var ADispose: Boolean );
begin
  SetHitList( AResult );
  ADispose := False;

  FQueryWatch.Stop;

  if Assigned( AException ) then
    StatusBar1.Panels[ 1 ].Text := AException.ToString( )
  else
    StatusBar1.Panels[ 1 ].Text := string.Format( 'query finished in (%d ms)', [ FQueryWatch.ElapsedMilliseconds ] );

end;

procedure TForm1.QueryData( const QueryStr: string );
var
  LQueryStrArr: TArray<string>;
begin
  StatusBar1.Panels[ 1 ].Text := 'query data...';

  FQueryWatch := TStopwatch.StartNew;

  if QueryStr.Trim( ) = '' then
    FAllList.Query(
      function( AFileInfo: TFileInfo ): Boolean
      begin
        Result := True;
      end, QueryCallback )
  else
  begin
    LQueryStrArr := QueryStr.ToLower( ).Split( [ ' ' ] );
    FAllList.Query(
      function( AFileInfo: TFileInfo ): Boolean
      var
        LQueryStr: string;
      begin
        for LQueryStr in LQueryStrArr do
        begin
          if not AFileInfo.FullName.ToLower.Contains( LQueryStr ) then
            Exit( False );
        end;
        Result := True;
      end, QueryCallback );
  end;
end;

procedure TForm1.QueryTimerTimer( Sender: TObject );
begin
  TTimer( Sender ).Enabled := False;
  QueryData( Edit1.Text );
end;

procedure TForm1.SetHitList( AHitList: TFileInfoList );
begin
  if ( FHitList <> FAllList ) and ( FHitList <> AHitList ) then
    FreeAndNil( FHitList );
  FHitList := AHitList;

  if Assigned( FHitList ) then
  begin
    ListView1.Items.Count := FHitList.Count;
    ListView1.Repaint;
  end
  else
  begin
    ListView1.Items.Count := 0;
  end;

  ListView1.Visible := Assigned( FHitList );

  StatusBar1.Panels[ 0 ].Text := ListView1.Items.Count.ToString( );
end;

end.

juergen 6. Jul 2015 16:08

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
@SirRufo,
DAS sieht sehr interessant aus! :-D (deinen letzten Post habe ich erst nach dem Abschicken gesehen...)
Vielen Dank für deine Geduld. Im Moment habe ich kein Zugriff auf Delphi. Bevor ich versuche das heute Abend zu verstehen eine wichtige Frage vorab: Besteht mit diesem Konzept auch die Möglichkeit die Daten zu speichern und beim Starten des Programms wieder zu laden? Und WIE genau fülle ich die TObjectList mit den Daten?

@freimatz,
ich gebe dir zum Teil Recht. Ich nutze Delphi hobbymäßig und habe schon einiges gelernt, aber bei weitem nicht die "komplzierteren Sachen". Das eigentliche Konzept wird wohl bleiben. Eine angepasste StringList für die reine Suche der Dateinamen mit "Referenzzeiger" auf die "Master"-StringList, Ich habe bis jetzt keine Alternativen erkannt (Schnelligkeit der Suche).
Wo du Recht hast ist natürlich die Datenhaltung in der "Master"-StringList. Da hat Sir Rufo gerade eine sehr interessante Alternative aufgezeigt. Wenn sich das ganze auch abspeichern und neu laden lässt wäre ich ja weg von der "einfachen" StringList. 8-)
Ich muss aber auch abwägen: Mit welchem für mich VERTRETBAREN Aufwand kann ich WAS umsetzen...:oops:


Edit Roter Kasten: Oh Mann, vielen Dank für deine Mühe. Ich werde mir das heute Abend anschauen und freu mich schon drauf.:)

Perlsau 6. Jul 2015 17:05

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Zitat:

Zitat von juergen (Beitrag 1307833)
Besteht mit diesem Konzept auch die Möglichkeit die Daten zu speichern und beim Starten des Programms wieder zu laden? Und WIE genau fülle ich die TObjectList mit den Daten?

Eine Objektliste füllt man mit Daten, indem man ein Objekt erzeugt und der Objektliste hinzufügt (Add). Zurück erhält man den Index des neu hinzugefügten Objekts. Steht übrigens alles in der Online-Hilfe zu TObjectList ...
Da es sich beim Inhalt des Objekts um reinen Text handelt (auch Datumse kann man als String abspeichern), genügt z.B. eine CSV-Datei (Comma Separated Values), die man via Stringliste einliest und die einzelnen Strings via DelimitedText voneinander trennt. Eine solche Speichermethode könnte z.B. so aussehen:
Delphi-Quellcode:
Procedure FormMain.Speichern(Const Dateiname : String);
Const
  K = ';';
Var
  i,z : Integer;
  Liste : TStringList;
Begin
  Liste := TStringList.Create;

  Try
    z := MyObjectList.Count;
    If z > 0 Then
    For i := 0 To z-1 Do
      Liste.Append(MyObjectList.Dateiname + K + DateTimeToStr(MyObjectList.Datum));

    Liste.SaveToFile(Dateiname);
  Finally
    Liste.Free;
  End;
End;
Ähnlich würde dann das Einlesen erfolgen:
Delphi-Quellcode:
Procedure FormMain.Einlesen(Const Dateiname : String);
Const
  K = ';';
Var
  DList,
  Liste : TStringList;
  Id,
  i,z : Integer;
  Obj : TMyObjekt;

Begin
  Liste := TStringList.Create;
  DList := TStringList.Create;

  Try
    Anzahl := 0;
    DList.Delimiter := K;
    DList.StrictDelimiter := True;
    Liste.LoadFromFile(Dateiname);
    z := Liste.Count;
    If z > 0 Then
    For i := 0 To z-1 Do
    Begin
      DList.DelimitedText := Liste[i];
      If DList.Count = 2 Then
      Begin
        Obj := TMyObjekt.Create;
        Obj.Dateiname := DList[0];
        Obj.Datum := StrToDateTime(DList[1]);
        Id := MyObjectList.Add(Obj);
        If Id < 0 Then Obj.Free; // dann ist nämlich das Add mißlungen und das Objekt muß freigegeben werden
      End;
    End;
  Finally
    DList.Free;
    Liste.Free;
  End;
  ShowMessage('Es wurden ' + IntToStr(MyObjectList.Count) + 'Objekte eingelesen ...');
End;
Alles ohne Gewähr, da frei in den Editor getippt und daher ungetestet.

juergen 6. Jul 2015 20:25

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
@Sir Rufo,
dein Projekt habe ich mir angesehen. Was soll ich sagen...außer Danke für etliche Denkanstöße. Aber ehrlich gesagt verstehe ich auch vieles nicht. Ich habe aber wieder einiges dazugelernt. Interessant ist aber auch die IOUtils-Unit mit den vielen Eigenschaften wie z.B. Predicate und das verwenden von mehreren Directories.

Ich werde nun erst mal klein anfangen und meine Master-StringList umstellen auf TObjectList! Mit den ganzen Beispielen bekomme ich das hin, denke ich.

@Perlsau,
auch dir danke ich für die Denkanstöße. TObjectList scheint mir nun immer sympatischer und vom Gefühl her denke ich dass es das richtige ist.
:-D

Perlsau 6. Jul 2015 21:17

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Zitat:

Zitat von juergen (Beitrag 1307890)
@Perlsau,
auch dir danke ich für die Denkanstöße. TObjectList scheint mir nun immer sympatischer und vom Gefühl her denke ich dass es das richtige ist.:-D

Dann hat sich der Aufwand also gelohnt: Man konnte dich von einem besseren Konzept überzeugen, denn das war ja auch dein eigentliches Anliegen :thumb:

Die Welt ist schön :-D

Bentissimo 7. Jul 2015 10:23

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Wenn ohnehin schon das QuantumGrid im Einsatz ist, wäre der Einsatz der TdxMemData Komponente in Verbindung mit der Property Options.IncSearch für ausgewählte Spalten vielleicht eine Überlegung wert.

Das Speichern und Laden beherrscht diese Komponente bereits und die Suche wäre ebenfalls zumindest schon zum Teil abgedeckt.

Erfüllt die Anforderung vielleicht noch nicht zu 100%, aber dafür lässt sich ein Prototyp vermutlich in einer Stunde zusammen bauen.

striderx 10. Jul 2015 18:06

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Zitat:

In der ersten TStringList werden Dateipfad+Name (und jetzt neu) das Datum gespeichert (getrennt durch 5 Doppelpunkte).
Vielleicht verstehe ich ja etwas grundsätzlich nicht, aber warum nimmst Du nicht einfach ein dynamisches Array? Und fünf Doppelpunkte als Feldtrenner sollten nicht ernsthaft eine Lösung sein.

Delbor 12. Jul 2015 12:13

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Hi striderix
Zitat:

Vielleicht verstehe ich ja etwas grundsätzlich nicht, aber warum nimmst Du nicht einfach ein dynamisches Array?
Weil TObjectlist mit weniger eigenem Aufwand viel flexibler ist? Ausserdem braucht ein dynamisches Array bei jeder Grössenänderung zusätzlich Rechenzeit.

Gruss
Delbor

Dejan Vu 12. Jul 2015 12:57

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Soweit ich mich erinnere wird eine TObjectList intern auch nur über ein dynamisches Array (PPointerList) abgebildet. Der Speicherverbrauch ist auch nicht gerade optimal.

Aber man will ja schließlich die Listenverwaltung kapseln. Ergo wäre es ziemlich blöd, ein Array zu verwenden, und den ganzen Verwaltungsgedöns selbst zu programmieren. Aber wer's mag...

striderx 12. Jul 2015 16:29

AW: Konzeptfrage: Datenhaltung vieler Datei-Infos und deren Darstellg mit schneller S
 
Zitat:

Ausserdem braucht ein dynamisches Array bei jeder Grössenänderung zusätzlich Rechenzeit.
Und bei einer Object-Liste passiert das in Nullzeit? Siehe auch Hinweis von Dejan Vu.

Zitat:

Ergo wäre es ziemlich blöd, ein Array zu verwenden, und den ganzen Verwaltungsgedöns selbst zu programmieren. Aber wer's mag...
Wenn du mit 'Verwaltungsgedöns' das einfügen und Löschen von Einträgen meinst, dann hast du grundsätzlich recht. Im Moment sehe ich aber nur, dass der TE einen String und ein Datum speichern und in der Liste suchen will. Und mir ging es vor allem darum, dass eine StringList und fünf Doppelpunkte als Feldtrenner nun gar keinen Sinn macht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:43 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