delphi 将TObject保存到文件

tgabmvqs  于 2023-10-18  发布在  其他
关注(0)|答案(7)|浏览(160)

如何保存一个对象,在其当前状态,到一个文件?以便可以立即读取并恢复其所有变量。

rjzwgtxy

rjzwgtxy1#

你的问题已经得到了很好的答案。根据实际操作,可能需要使用预构建的库或组件来保存对象。这是一个便宜而漂亮的库/组件集,使得持久化和恢复对象变得微不足道,并且非常容易(即,使用一点代码)容纳持久化甚至未发布的对象成员:http://www.deepsoftware.ru/rsllib/index.html不是什么高深莫测的东西,但如果你要做很多这类事情,这个组件为它提供了一个很好的框架。
Developer Express还包括一个通用的cxProperties Store组件,作为随其某些组件提供的SDK编辑器库的一部分。

a5g8bdjr

a5g8bdjr2#

你正在寻找的东西被称为对象持久性。这个article可能会有帮助,如果你在google上搜索“ Delphi 持久化对象”,还有很多其他的。

0ve6wy6x

0ve6wy6x3#

如果你从TComponent中继承你的对象,你可以使用一些内置的功能来将对象流到一个文件中。我认为这只适用于简单的对象。
一些示例代码让你开始:

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.
piztneat

piztneat4#

如前所述,最简单的方法是使用Stream及其WriteComponentReadComponent方法。
但是要注意

  • 它适用于TComponent的后代,而不是普通的TObject;
  • 用于已发布的属性(保存在dfm中的属性),不用于公共属性,也不用于私有属性(更不用说);
  • 恢复组件时,需要特别注意Name属性
    你可能会在这些SO答案中找到一些可以使用的代码:在 Delphi 中运行时替换可视组件,在运行时复制组件
hs1rzwqc

hs1rzwqc5#

在S.O.上也有一个自己卷XML method

gwo2fgha

gwo2fgha6#

解决方案1.您可以使用JVCL TJvAppXMLFileStorage(参见下面的代码)。但JVCL是巨大的!你要不要考虑一下,拖着这么大一个依赖,一辈子。
解决方案2.保存你的对象到一个二进制文件(我的首选解决方案)。相信我,没那么难。在我的LightSaber Core library中使用ccStreamMem.pas,或者更好的ccStreamBuff.pas(缓冲写入)。
Delphi in all its glory书中有一些关于如何做到这一点的代码示例。
PS:LightSaber是JVCL的轻量级替代品。
下面是一个如何将记录保存到二进制文件的示例。操作与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;

结尾处的填充允许您稍后更改记录/对象结构,而无需更改二进制文件的格式。
要将RAnimationParams实际保存到磁盘,您只需执行以下操作:

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

当你想从Test.bin中加载RAnimationParams时,代码是一样的,但是你使用的是写而不是读。
TCubicBuffStream类甚至有专门的函数,如ReadHeader/ReadWrite,允许您轻松地向二进制文件添加“文件魔法号”和“文件版本号”。
看到没那么难它将适用于任何对象,而不仅仅是TComponent。
JVCL的示例,但它不适用于TObject,而仅适用于持久化派生:

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;
92dk7w1h

92dk7w1h7#

There is a good tutorial here。记住,你必须有RTTI(运行时类型信息)来使用这种方法在运行时保存对象,所以它只会捕获类的发布的属性。

相关问题