Delphi object persistence, what is the best way
Asked Answered
S

7

8

I have developed application for drawing some shapes (lines mostly) , now i need to be able to store sketch to a file, I know that delphi has build in routines for object persistence, but I have never used it.

Can someone tell me can object persistence be used if i have to persist object that have also references to other objects (that will be stored to), I have TLine object which can be connected to other TLine object etc.

Is it better to use this feature or write custom procedure to store/read object to/from file.

Spiritless answered 28/12, 2008 at 19:22 Comment(0)
C
3

One method that I have used in the past is to store my object properties in an XML file writing a custom "save" routine which adds to a passed IXMLNode, and a new constructor which reads from a passed IXMLNode. I store component as a node, and the properties as attributes (unless the property is another object, then it would be a child node).

I believe there are some routines in the Delphi Jedi project which will handle component streaming for you, but I have not used them directly as most of my XML streaming has been done by hand since my objects were extremely simple and could be rendered with only a handful of properties.

Contractor answered 29/12, 2008 at 3:15 Comment(0)
C
5

The built in object persistance is primarily designed for use in streaming components to a dfm, the work that you would need to do to persist your sketch would not benefit very much from that mechanism.

I think that you would be better off coming up with a custom scheme.

Cubbyhole answered 28/12, 2008 at 20:37 Comment(0)
C
3

One method that I have used in the past is to store my object properties in an XML file writing a custom "save" routine which adds to a passed IXMLNode, and a new constructor which reads from a passed IXMLNode. I store component as a node, and the properties as attributes (unless the property is another object, then it would be a child node).

I believe there are some routines in the Delphi Jedi project which will handle component streaming for you, but I have not used them directly as most of my XML streaming has been done by hand since my objects were extremely simple and could be rendered with only a handful of properties.

Contractor answered 29/12, 2008 at 3:15 Comment(0)
B
3

I use the TI Object persistence framework (tiopf.com). I wrote the overview at http://tiopf.sourceforge.net/Doc/overview/index.shtml.

It will let you save objects and lists to xml, csv, databases etc. It handles child objects automatically.

If you are interested, use the svn version, not the sourceforge download as it has more features (inc partial D 2009 support).

Byrdie answered 29/12, 2008 at 4:19 Comment(0)
K
2

You also can use the famous hibernate know from java.

the delphi port you can find here: dHibernate

Kaykaya answered 3/1, 2009 at 0:32 Comment(0)
A
2

JSON is a new and very compact way to store objects. Two libraries are available for Delphi: SuperObject and lkJSON.

Accumulate answered 21/3, 2009 at 18:28 Comment(1)
Delphi 2010 has added few units for JSON and Datasnap, but you can them without datasnap.Plea
A
1

With NativeXML from http://www.simdesign.nl/xml.html I accomplished to read/write delphi in-memory objects from/to XML code. Very nice, very easy, with demo included here: http://www.simdesign.nl/forum/download/file.php?id=236

Apathetic answered 15/6, 2013 at 20:25 Comment(0)
C
1

Solution 1. You can use JVCL TJvAppXMLFileStorage. But JVCL is huge!! You have to consider twice if you want or not, to drag such a huge dependency after you, your whole life.

Solution 2. Save your object to a binary file (my preferred solution). Believe me, it is not that hard. Use the ccStreamMem.pas, or even better the ccStreamBuff.pas (buffered writing) in my LightSaber Core library.
You have some code examples on how to do it, in Delphi in all its glory book.
PS: LightSaber is a lightweight alternative to JVCL.

Here is an example of how to save a record to a binary file. The operation is identical for TObject!

// Supposing you have a record (could be also an object) called RAnimationParams that you want to save to disk:

INTERFACE

USES
  System.SysUtils, Vcl.Graphics, ccStreamBuff;

TYPE
  TFrameDelayType = (fdAuto, fdUser);

  RAnimationParams = record
    Color         : TColor;          
    DelayType     : TFrameDelayType;
    procedure WriteToStream (IOStream: TCubicBuffStream);
    procedure ReadFromStream(IOStream: TCubicBuffStream);
  end;

IMPLEMENTATION

procedure RAnimationParams.WriteToStream(IOStream: TCubicBuffStream);
begin
 IOStream.WriteByte    (Ord(DelayType));
 IOStream.WriteInteger (Color);
 IOStream.WritePadding (32);
end;

procedure RAnimationParams.ReadFromStream(IOStream: TCubicBuffStream);
begin
 DelayType    := TFrameDelayType(IOStream.ReadByte);
 Color        := IOStream.ReadInteger;
 IOStream.ReadPadding (32);
end;

The padding at the end allows you to change your record/object structure later, without changing the format of your binary file.

To actually save the RAnimationParams to disk you just do:

MyBinFile:= TCubicBuffStream.CreateRead('C:\Test.bin');
AnimationParams.WriteToStream(MyBinFile);
MyBinFile.Free;

Same code when you want to load the RAnimationParams back from Test.bin, but you use CreateWrite instead of CreateRead.

The TCubicBuffStream class has even dedicated functions such as ReadHeader/CreateWrite that allow you to easily add "file magic numbers" and "file version numbers" to your binary files.

See? Not so difficult. And it will work for any object, not only for TComponent.

Cutlass answered 6/8, 2023 at 19:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.