Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TPersistent & Streaming (https://www.delphipraxis.net/67222-tpersistent-streaming.html)

EConvertError 11. Apr 2006 13:27


TPersistent & Streaming
 
Hallo!

Ich versuche immer noch meine Objekte automatisiert in eine XML Datei zu speichern (serialisieren).
Diesmal möchte ich mich etwas von Delphi-Streaming-System inspirieren lassen.

Dazu meine Fragen:
1)Wie kann ich von TPersistent abgeleitete Objekte in einen Stream speichern?
Ich habe schon viele Beispiele für TComponent gesehen, aber diese für TPersistent umzubauen schaffe ich aufgrund meines (noch) zu kleinen RTTI Wissens noch nicht.

2)Außerdem habe ich gesehen, dass in den Beispielen oft TWriter-Objekte direkt erstellt werden, was laut meiner OH nicht getan werden soll. Ist das eine gute Idee?

3) Ist es überhaupt eine gute Idee/bzw. guter Stil, das Delphi-Streaming-System dazu zu missbrauchen(Oder: Ist es überhaupt Missbrauch?)? Published properties für properties, die "eigentlich" nur public sein müssten, usw.?

Vielen Dank,
Andreas

EConvertError 12. Apr 2006 11:36

Re: TPersistent & Streaming
 
Da mir noch niemand geantwortet hat, möchte ich hinzufügen, dass sich Frage 1) auf die ganz normale Variante (also ohne XML) bezieht. Vielleicht war das etwas unklar ausgedrückt von mir...

Die XML-Geschichte möchte ich selbst implementieren, nachdem ich herausgefunden habe, wie das normale Streaming von TPersistent funktioniert.
Außer irgendein XML-Parser unterstützt so etwas schon von Haus aus.


Andreas

Khabarakh 12. Apr 2006 11:47

Re: TPersistent & Streaming
 
Zitat:

Zitat von EConvertError
1)Wie kann ich von TPersistent abgeleitete Objekte in einen Stream speichern?
Ich habe schon viele Beispiele für TComponent gesehen, aber diese für TPersistent umzubauen schaffe ich aufgrund meines (noch) zu kleinen RTTI Wissens noch nicht.

Mit public Membern von TStream/TWriter geht das AFAIK nicht.
Zitat:

Zitat von http://www.delphipraxis.net/internal_redirect.php?p=529907#529907
Delphi-Quellcode:
type
  TSettings = class(TComponent) // wer unbedingt TPersistent will, kann immer noch bspw. per Class-Hack TWriter.WriteProperties benutzen
  ...

Zitat:

2)Außerdem habe ich gesehen, dass in den Beispielen oft TWriter-Objekte direkt erstellt werden, was laut meiner OH nicht getan werden soll. Ist das eine gute Idee?
Kommt drauf an ;) . Solange die Methoden reichen, würde ich bei TStream bleiben.

Zitat:

3) Ist es überhaupt eine gute Idee/bzw. guter Stil, das Delphi-Streaming-System dazu zu missbrauchen(Oder: Ist es überhaupt Missbrauch?)? Published properties für properties, die "eigentlich" nur public sein müssten, usw.?
:gruebel: Der einzige Sinn von published ist es, die Property für die RTTI, also in erster Linie fürs Streaming, sichtbar zu machen. published ist nichts anderes als [Serializable], nur etwas unschöner ;) .

EConvertError 12. Apr 2006 11:59

Re: TPersistent & Streaming
 
Danke erstmal!

Ja ich würde schon gerne TPersistent anstatt TComponent nutzen. Ganz nach dem Motto: So schlank wie möglich! :wink:

Aber mir sagt Class-Hack, um ehrlich zu sein gar nichts (Außer, dass es sich etwas unelegant anhört). Irgendwie muss das aber auch sauber gehen, weil es ja in der OH heißt, dass TPersistent als Basisklasse für alle Klassen dient, die keine Komponenten sind (also, so wie ich das verstehe: kein TComponent), aber trotzdem gestreamt werden müssen.

Mein Plan ist ja der, dass ich jetzt mal untersuche, wie dieses Streaming genau funktioniert, und danach mein eigenes XML-Streaming-System schreibe (Bin ein kleiner XML-Fan :-D ).

Andreas

shmia 12. Apr 2006 12:44

Re: TPersistent & Streaming
 
Also ich denke, dass das vorhandene Streaming-Konzept von Delphi
für dein Vorhaben zu unflexibel ist.
Alles baut auf dem DFM-Format und den Streams auf.
Dies fängt schon bei der Klasse TFiler an.
Also kannst du alles, was von TFiler abgeleitet ist (TReader & TWriter) leider nicht benutzen.
DOT-NET oder Java JDK ist das um einiges flexibler, da dort mit Interfaces gearbeitet wird.

Khabarakh 12. Apr 2006 13:28

Re: TPersistent & Streaming
 
@EConvertError: Frag's Pferd, warum es keine direkte Möglichkeit für TPersistent gibt. WriteComponent ist zwar auf Komponenten (ComponentState usw. wird angepasst) ausgelegt, aber man hätte doch trotzdem eine Lightweight-Lösung einbauen können.
Zum Class-Hack: Hört sich schlimmer an, als es ist ;) . WriteData, das von WriteComponent aufgerufen wird, schreibt den Namen der Klasse in den Stream (WriteStr) und ruft danach WriteProperties auf. Um auf die protected Methode zugreifen zu können, kannst du einfach von TWriter ableiten (ohne neue Member) und damit in der gesamten Unit auf protected Member zugreifen. In diesem Falle bietet es sich aber wohl eher an, der abgeleiteten Klasse einfach eine WritePersistent-Methode zu spendieren.

@shmia: So wie ich ihn verstanden habe, will er erst einmal das DFM-Streaming erkunden. Später wird er - wie du sagtest - sich von TFiler verabschieden und Get/SetXYZProp direkt ansteuern müssen (wobei man dafür gut TWriter.WriteProperties als Vorlage nehmen kann).

EConvertError 12. Apr 2006 13:47

Re: TPersistent & Streaming
 
Zugegeben, ich habe mich etwas von der .NET-Serialisierung inspirieren lassen. :wink:
Mir ist schon klar geworden, dass ich so etwas komfortables in Delphi (Win32) nie haben werde.

Genau, Khabarakh: Ich möchte wissen, wie man an die published-Eigenschaften (Name+Wert) rankommt und dann meinen eigenen TXmlWriter schreiben.

Allerdings geht es mir eher darum, dass ich 4-5 Klassen in meinem aktuellen Projekt habe, welche ich in eine XML-Datei speichern können muss. Dieses "automatische Speichern", sodass ich die Eigenschaften nicht mehr manuell zuweisen muss, ist mir hierbei nicht einmal von so großer Bedeutung (Wobei es natürlich äußerst praktisch wäre).

Ich habe auch schon an eine gemeinsame Basisklasse gedacht, die folgende Methoden hat:
Delphi-Quellcode:
procedure SaveToXML(const XmlDoc: IXMLDocument);
procedure LoadFromXML(const XMLDoc: IXMLDocument);
Der Haken hierbei ist: IXMLDocument (und IXMLNode) unterstützen kein WriteString(), WriteDate(), etc., wie es z.B. das TIniFile oder TRegistry tut. Das bedeutet, dass ich total viel doppelten Code in den einzelnen LoadFromXML/SaveToXML-Methoden habe. Freilich könnte ich von IXMLDocument eine Klasse ableiten, wobei ich hier wieder auf die Schwierigkeit stoße, wie ich die beliebigen Verschachtelungen, die bei XML möglich sind, manage.

Wenn möglich, würde ich gerne beim Delphi-eigenen-IXMLDocument bleiben, aber wenn es sein muss verwende ich auch MSXML.

[EDIT]Und dieses "Serialisierung" würde mich von derartigen Sorgen befreien (Schafft natürlich auch neue :mrgreen: ). Wenn ihr was Besseres wisst, dann her damit. :wink:

Vielen Dank für eure Hilfe,
Andreas

EConvertError 14. Apr 2006 18:29

Re: TPersistent & Streaming
 
Wie man an die Properties und deren Werte kommt, habe ich anhand TWriter schon herausfinden können. Ein viel größeres Problem ist die DefineProperties() Methode von TPersistent. Die erfordert nämlich einen TFiler.

Von TFiler ableiten sieht auch nicht gut aus, weil das wieder auf TComponent aufbaut.

Weiß noch wer Rat, oder habe ich den Haken an der Geschichte gefunden?

Andreas

maximov 18. Apr 2006 13:04

Re: TPersistent & Streaming
 
Da hast du dir was vorgenommen. Kann ich gut verstehen, denn ich hab für ein objektmodell auch mal das komplette dfm-streamingsystem aufgebohrt und für meine zwecke erweitert. Deshalb kann ich dir, aus eigener erfahrung, nur abraten! Es ist einfach zu unflexible und starr mit TComponent verwachsen. Tu dir selbst einen gefallen und schau dich nach einer alternativen lösung um. Persistierungsysteme gibt es sicher schon genug...

spontan fällt mir dieses ein http://www.kasparsoft.de/RakBinaryStreamData/index.htm ...wobei ich es noch nie getestet oder benutzt habe.


Ich würde schon gerne eins schreiben, finde aber leider momentan nicht die zeit. Ich würde dir auf jeden falls empfehlen wiederverwendbare Softwaremuster (Entwurfsmuster. Elemente wiederverwendbarer objektorientierter Software) zu studieren, wenn du ein solches system selbst auf die beine stellen willst. Die Entwurfsmuster helfen dir aber auch in jeder anderen lebenslage...na gut fast jeder...naja eingentlich nur beim zeitvergeuden;)

EConvertError 19. Apr 2006 13:01

Re: TPersistent & Streaming
 
Danke.

Ich nehme deinen Rat an. :wink:

Eine bestehende Lösung möchte ich nicht verwenden (z.B. RakBinaryStreamData).

In diesem Fall werde ich meine Objekte "ganz normal" und ganz ohne RTTI-Zauber speichern.

Vielen Dank für eure Unterstützung,
Andreas


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