views:

635

answers:

7

How can one save an Object, in its current state, to a file? So that it can immediately be read and restored with all its variables.

+2  A: 

What you are looking for is called object persistance. This article might help, and there are many others if you google for "delphi persisting objects".

Adrian Grigore
+1  A: 

There is a good tutorial here. Keep in mind that you have to have RTTI (run time type information) to save an object at run-time using this approach, so it will only capture published properties of a class.

JosephStyons
+2  A: 

There's also a roll-your-own XML method here on S.O.

dwc
+1  A: 

If you descend your object from TComponent, you can use some built-in functionality to stream the object to a file. I think this only works well for simple objects.

Some sample code to get you started:

unit Unit1;

interface

uses
  Classes;

type
  TMyClass = class(TComponent)
  private
    FMyInteger: integer;
    FMyBool: boolean;
    FMyString: string;
  public
    procedure ToFile(AFileName: string);
  published
    property MyInteger: integer read FMyInteger write FMyInteger;
    property MyString: string read FMyString write FMyString;
    property MyBool: boolean read FMyBool write FMyBool;
  end;

implementation

{ TMyClass }

procedure TMyClass.ToFile(AFileName: string);
var
  MyStream: TFileStream;
begin
  MyStream := TFileStream.Create(AFileName);
  try
    Mystream.WriteComponent(Self);
  finally
    MyStream.Free;
  end;
end;

end.
birger
+3  A: 

As already stated, the easiest way is to use a Stream and its WriteComponent and ReadComponent methods.
But be aware that :
- it works for descendants of TComponent, not plain TObject;
- only for the published properties (those saved in a dfm), not the public ones nor (a fortiori) the privwte ones;
- you have to pay a special attention for the Name property when restoring the component.

You may find some code you could use in these SO answers: Replace visual component at runtime in Delphi, Duplicating components at Run-Time

François
A: 

You've already gotten some good answers to your question. Depending on what you're actually doing, it might be desirable to use a pre-built library or component to save objects. This is an inexpensive and nifty library/component set that makes it trivial to persist and restore objects, and pretty easily (i.e., with a little bit of code) accommodates persisting even unpublished members of an object: http://www.deepsoftware.ru/rsllib/index.html Not something that's rocket science, but if you're doing a lot of this sort of thing this component provides a nice framework for it.

Developer Express also includes a general purpose cxPropertiesStore component as part of the ExpressEditors library that comes with some of their components.

Herbert Sitz
A: 
  1. Very simple and efficient solution: DragonSoft's XML Class Serializer
  2. Also you can use JVCL TJvAppXMLFileStorage:

    uses JvAppXMLStorage;

    var
      Storage: TJvAppXMLFileStorage;
    begin
      Storage := TJvAppXMLFileStorage.Create(nil);
      try
        Storage.WritePersistent('', MyObject);
        Storage.Xml.SaveToFile('S:\TestFiles\Test.xml');
        Storage.Xml.LoadFromFile('S:\TestFiles\Test.xml');
        Storage.ReadPersistent('', MyObject);
      finally
        Storage.Free;
      end;
    end;
    
Altar