Delphi语言怎样对自己定义类进行持久化保存及恢复 (性能远比json/xml高)
Delphi的RTL自身就带有一套非常好的资源持久化保存(IDE设计窗口时,保存为DFM格式及编译到EXE里面的资源文件)及恢复机制(EXE启动时对窗口资源的载入),那么应不是必需再额外用xml/json格式保存程序的參数了。我们大能够将參数集中在一个參数类里面,然后通过这套机制进行保存及恢复。
因为我们的參数类型可能五花八门。除了传统的整数、小数、字符串、true/false、还有可能是数组、列表、枚举等,则须要override DefineProperties这个函数来自己定义属性的保存及恢复。
废话少说,给出代码,此代码演示了怎样自己定义数据的保存及恢复、以及保存整个Form:
unit Unit1; interface uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type
TArrayOfInteger = array of integer; TSetting = class(TComponent)
private
fIntVal: integer;
fIntArr: TArrayOfInteger;
procedure ReadIntArr(Reader: TReader);
procedure WriteIntArr(Writer: TWriter);
protected
procedure DefineProperties(Filer: TFiler); override;
public
property intArr: TArrayOfInteger read fIntArr write fIntArr; published
property intval: integer read fIntVal write fIntVal;
end; TForm1 = class(TForm)
btnCloneClass: TButton;
mmo1: TMemo;
btnCloneForm: TButton;
procedure btnCloneClassClick(Sender: TObject);
procedure btnCloneFormClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; var
Form1: TForm1; implementation {$R *.dfm}
{ TSetting } procedure TSetting.DefineProperties(Filer: TFiler);
begin
inherited;
Filer.DefineProperty('intArr', ReadIntArr, WriteIntArr, true);
end; procedure TSetting.ReadIntArr(Reader: TReader);
var
lvIdx: integer;
begin
fIntArr := nil;
Reader.ReadListBegin;
SetLength(fIntArr,Reader.ReadInteger);
lvIdx:=low(fIntArr);
while not Reader.EndOfList do
begin
fIntArr[lvIdx] := Reader.ReadInteger;
inc(lvIdx);
end;
Reader.ReadListEnd;
end; procedure TSetting.WriteIntArr(Writer: TWriter);
var
i: integer;
begin
Writer.WriteListBegin;
Writer.WriteInteger(integer(Length(fIntArr)));
for i := Low(fIntArr) to High(fIntArr) do
begin
Writer.WriteInteger(fIntArr[i]);
end;
Writer.WriteListEnd;
end; function ClassToStr(pvClass: TComponent): ansiString;
var
inStream, outStream: TMemoryStream; begin
inStream := TMemoryStream.Create;
outStream := TMemoryStream.Create;
try
inStream.WriteComponentRes(pvClass.ClassName, pvClass);
// inStream.WriteComponent(pvClass);
inStream.Position := 0;
ObjectResourceToText(inStream, outStream);
// ObjectBinaryToText(inStream,outStream);
outStream.Position := 0;
SetLength(Result, outStream.Size + 1);
FillChar(Result[1], outStream.Size + 1, 0);
outStream.ReadBuffer(Result[1], outStream.Size);
finally
FreeAndNil(inStream);
FreeAndNil(outStream);
end;
end; function StrToClass(pvStr: ansiString; pvCmpToSetProperties: TComponent=nil): TComponent;
var
inStream, outStream: TMemoryStream;
begin
inStream := TMemoryStream.Create;
outStream := TMemoryStream.Create;
try
if (pvStr <> '') then
inStream.WriteBuffer(pvStr[1], length(pvStr));
inStream.Position := 0;
ObjectTextToResource(inStream, outStream);
// ObjectTextToBinary(inStream,outStream);
outStream.Position := 0;
Result := outStream.ReadComponentRes(pvCmpToSetProperties);
finally
FreeAndNil(inStream);
FreeAndNil(outStream);
end; end; procedure TForm1.btnCloneClassClick(Sender: TObject);
var
lvObj, lv1: TSetting;
lvStr: String;
lvArr: TArrayOfInteger;
begin
lvObj := TSetting.Create(nil);
try
lvObj.intval := 12345;
SetLength(lvArr, 3);
lvArr[0] := 222;
lvArr[1] := 333;
lvArr[2] := 444;
lvObj.intArr := lvArr;
lvStr := ClassToStr(lvObj);
RegisterClass(TSetting);
lvObj.intval := 1;
lv1 := TSetting(StrToClass(lvStr, nil));
if (lv1.intval > lvObj.intval) then
mmo1.Text := lvStr;
finally
FreeAndNil(lvObj);
FreeAndNil(lv1);
end;
// WriteComponentResFile(ExtractFilePath(ParamStr(0))+ 'd.res',self);
end; procedure TForm1.btnCloneFormClick(Sender: TObject);
var lvNewForm:TForm1;
lvRes:string;
begin
lvRes:=ClassToStr(self);
RegisterClass(TForm1);
lvNewForm:=TForm1.CreateNew(application);
StrToClass(lvRes,lvNewForm);
lvNewForm.Left:=self.Left+50;
lvNewForm.Top:=self.Top+50; end; end.
Delphi语言怎样对自己定义类进行持久化保存及恢复 (性能远比json/xml高)的更多相关文章
- Delphi实现类的持久化保存(DFM格式)
var inStream,outStream:TMemoryStream; begin inStream:=TMemoryStream.Create; outStream:=TMemoryStream ...
- JavaScript定义类的方式与其它OO语言有些差异
JavaScript面向对象的程序编写与其它OO语言有一些出入,所以使用JavaScript的面向对象特性的时候,需要注意一些规范性的问题.下面就简单地谈一下,JavaScript如何定义一个类,在定 ...
- Javascript定义类(class)的三种方法
将近20年前,Javascript诞生的时候,只是一种简单的网页脚本语言.如果你忘了填写用户名,它就跳出一个警告. 如今,它变得几乎无所不能,从前端到后端,有着各种匪夷所思的用途.程序员用它完成越来越 ...
- 疯狂java学习笔记之面向对象(一) - 定义类、方法、构造器
Java面向对象 1.定义类 2.创建对象.调用方法 类和对象: 某一类对象的概念定义. 比如:人类 - 抽象出来的概念(不特指某个人) 对象 - 在类的概念下产生的一个实例,它就是一个对象了. ja ...
- JS中定义类的方法
JS中定义类的方式有很多种: 1.工厂方式 function Car(){ var ocar = new Object; ocar.color = "blue" ...
- Objective-C语言介绍 、 Objc与C语言 、 面向对象编程 、 类和对象 、 属性和方法 、 属性和实例变量
1 第一个OC控制台程序 1.1 问题 Xcode是苹果公司向开发人员提供的集成开发环境(非开源),用于开发Mac OS X,iOS的应用程序.其运行于苹果公司的Mac操作系统下. 本案例要求使用集成 ...
- [转]Javascript定义类的三种方法
作者: 阮一峰 原文地址:http://www.ruanyifeng.com/blog/2012/07/three_ways_to_define_a_javascript_class.html 将近2 ...
- Delphi语言获得生命的原因和过程
都说Anders Hejlsberg是Delphi语言的作者,前一阵仔细读了VCL源码,惊叹于它的巧夺天工,未免对编译器的作者有些不服气,觉得首功不是他.今天仔细想了想,还是觉得不服不行.以下是我的理 ...
- iOS Developer Libray (中文版)-- Defining Classes 定义类
该篇是我自己学习iOS开发时阅读文档时随手记下的翻译,有些地方不是很准确,但是意思还是对的,毕竟我英语也不是很好,很多句子无法做到准确的字词翻译,大家可以当做参考,有错误欢迎指出,以后我会尽力翻译的更 ...
随机推荐
- 在为知笔记中使用Markdown和思维导图
为知笔记Wiz是一款很好的网摘和笔记工具,作为为知的忠实用户,我在为知收费后第一时间就购买了两年的授权,毕竟这么多年积累的资料都在为知上,我也习惯了使用Wiz来做些工作相关的笔记.为知笔记自带Mark ...
- openstack学习心得:keystone 架构、概念、访问流程
1.keystone 介绍及其组成 OpenStack Identity 服务提供了一个单一的功能集合,包括管理认证,授权和服务目录. Identity 服务通常作为和用户第一个交互的服务.一旦认证成 ...
- C#操纵Excel,此工作薄包含嵌入对象,Office 2007的设定方法
C#操纵Excel,插入OLE对象时报“此工作薄包含嵌入对象,EXCEL可能无法从这些对象中删除个人信息.”, 如网上所述,Office 2003可以通过“菜单>>工具>>选项 ...
- 【分享】jQuery无插件实现 鼠标拖动图片切换 功能
前言 我就想随便叨逼叨几句,爱看就看几句,不爱看就直接跳过看正文就好啦~ 这个方法是仿写页面时我自己研究出来,可能有比我更简单的方法. 但我不管,因为我没查我不知道,我就觉得我的最好啦,耶耶耶~ 效果 ...
- Python异步处理
回调函数是实现异步操作的常用手法 1.callback版本的示例,其中framework调用logic,在完成某些操作或者接收到信号后,用callback返回异步结果 #!/usr/bin/env p ...
- eclipse项目中丢失的R包找回方法
当我们项目中的R文件丢失的时候会令我们痛苦不已,怎样找回呢?总不能删了吧,那样心血会毁于一旦的,我们肯定不会那样做,那要怎么办呢?我这里提供三种方法: 一,一般情况下这样: 方法一:选中 ...
- intel服务器cpu命名规则
我们以E3.E5.E7系列进行一个详细解析.首先,Intel E3.E5.E7代表了3个不同档次的至强CPU,至强"E系列"的这种命名方式有些类似桌面上的Core i3,i5,i7 ...
- Shell脚本数据备份
- 用python实现一个简单的词云
对于在windows(Pycharm工具)里实现一个简单的词云还是经过了几步小挫折,跟大家分享下,如果遇到类似问题可以参考: 1. 导入wordcloud包时候报错,当然很明显没有安装此包. 2. 安 ...
- 前端测试框架Jest系列教程 -- Asynchronous(测试异步代码)
写在前面: 在JavaScript代码中,异步运行是很常见的.当你有异步运行的代码时,Jest需要知道它测试的代码何时完成,然后才能继续进行另一个测试.Jest提供了几种方法来处理这个问题. 测试异步 ...