Sie sagen, dass Serialisierung keine Lösung ist, aber ich frage warum nicht? Ich habe so etwas in der Vergangenheit gemacht, aber hier ist, was ich getan habe.
Ich habe eine Komponentenklasse erstellt, die nur ein nicht TPersistant-basiertes Objekt serialisiert, sodass ich es mithilfe von VCL-Streaming-Funktionen ein- und ausstrahlen kann.
Zum Beispiel:
// Bitte vergib mir für die Fehler, die es gibt, wie ich versuche, dies von meinem Kopf von oben eingeben. Dies wird auch nicht funktional vollständig sein.
unit streamlist1;
interface
uses MyListObjectUnit;
procedure SaveList(fielname:string; data:TMyListObject);
procedure LoadList(filename:string; var data:TMyListObject);
implementation
type
TMyListStreamer = class(TComponent)
private
fMyList : TMyListObject;
procedure ReadList(Reader:TReader); //This is where the magic happens
procedure WriteList(Writer: TWriter); //This is where the magic happens (x2)
public
procedure DefineProperties(Filer: TFiler); override; //defined in TPersistent
procedure AssignMyList(data:TMyListObject);
procedure PopulateData(var data:TMyListObject);
end;
TMyListStreamer.procedure DefineProperties(Filer: TFiler); override; //defined in TPersistent
begin
Filer.DefineProperty('MyObjList', ReadList, WriteList, true);
//Filer.DefineBinaryProperty('MyObjList', ReadList, WriteList, true); //your choice
end;
procedure TMyListStreamer.ReadList(Reader:TReader); //This is where the magic happens
begin
//Use the reader class to read in anything you want...
end;
procedure TMyListStreamer.WriteList(Writer: TWriter); //This is where the magic happens (x2)
begin
//Use the writer class to write out anything you want...
end;
procedure SaveList(fielname:string; data:TMyListObject);
var
wFile : TFileStream;
wList : TMyListStreamer;
begin
RegisterClass(TMyListStreamer);
Try
wFile := TFileStream.Create(filename, fmcreate);
wList := TMyListStreamer.create(nil);
try
wList.AssignMyList(Data);
wFile.WriteComponent(wList);
finally
wFile.Free;
wList.free;
end;
finally
Unregisterclass(TMyListStreamer);
end;
end;
procedure LoadList(filename:string; var data:TMyListObject);
var
wFile : TFileStream;
wList : TMyListStreamer;
begin
RegisterClass(TMyListStreamer);
Try
wFile := TFileStream.Create(filename, fmOpenRead);
try
wList := TMyListStreamer(wFile.ReadComponent(Nil));
if assigned(data) and assigned(wList) then
wList.PopulateData(data);
if assigned(wList) then
wList.free;
finally
wFile.Free;
end;
finally
Unregisterclass(TMyListStreamer);
end;
end;
Mit dieser Methode können Sie beliebige Daten aus der VCL oder benutzerdefinierten Daten streamen (serialisieren). Es braucht ein wenig, um einzurichten, aber die Stärke ist, dass Sie alles in und aus der Datendatei steuern können. Sie können sogar mit einem kleinen Vorüberdenken ein Versions-Flag erstellen und verschiedene Daten verarbeiten, indem Sie bestimmte Daten in neueren Versionen des Programms/der Komponente ignorieren oder massieren.
Sie können sogar andere VCL-Objekte aus Ihrer Streaming-Komponente streamen, solange Sie den Objekttyp (dh TComponent/TPersistant-basierte Objekte) bereits mit den vorhandenen Methoden des TReader/TWriter kennen.
Nicht eine vollständige Lösung, aber es sollte Sie dorthin bringen, wo Sie mit ein wenig mehr Arbeit gehen wollen.
+1 das ist eine sehr gute Frage, in RTTI, Meta-Daten nur für veröffentlichte Abschnitt Felder verfügbar, aber von anderen Seite zeigt Debug-Inspektor alle Klassenfelder, so muss es eine Möglichkeit sein, dies zu tun. –
Warum sollten Sie eine Datei pro Objekt verwenden? Das wird natürlich langsamer und fehleranfälliger. – mghie
"Warum sollten Sie eine Datei pro Objekt verwenden?" ---- Du hast recht, aber ich bin erst am Anfang davon. Es wird sich auf die eine oder andere Weise zu einer einzigen Datei entwickeln. – Ampere