对象的序列化 -- 把一个 Object 变成字符串,再从字符串变回 Object |
|
pcplayer99
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
在 DELPHI 传统的 RTTI 基础上,可以把一个对象(必须是 TComponent)的 published 的属性序列化为字符串。这样做,必须满足:
1. 是 TComponent 或子类; 2. 必须注册这个类型。在 initialization 里面:RegisterClass(TPeer); 代码如下: //这个方法,将一个 TComponent 序列化为字符串。实际上只序列化了它的 published 的属性。 function ComponentToStringProc(Component: TComponent): string; var BinStream:TMemoryStream; StrStream: TStringStream; s: string; begin BinStream := TMemoryStream.Create; try StrStream := TStringStream.Create(s); try BinStream.WriteComponent(Component); BinStream.Seek(0, soFromBeginning); ObjectBinaryToText(BinStream, StrStream); StrStream.Seek(0, soFromBeginning); Result:= StrStream.DataString; finally StrStream.Free; end; finally BinStream.Free end; end; //这个方法,将字符串,反序列化为一个 TComponent. 具体序列化为哪个子类,就需要做类型转换,As TMyComponent。 //但必须要使系统知道这个子类,否则执行异常。要让系统知道子类型,就要在初始化 initialization 里面,用 RegisterClass(TPeer); 来注册。 function StringToComponentProc(Value: string): TComponent; var StrStream:TStringStream; BinStream: TMemoryStream; begin StrStream := TStringStream.Create(Value); try BinStream := TMemoryStream.Create; try ObjectTextToBinary(StrStream, BinStream); BinStream.Seek(0, soFromBeginning); Result:= BinStream.ReadComponent(nil); finally BinStream.Free; end; finally StrStream.Free; end; end; 调用上述两个函数的代码: Component 转换为字符串: procedure TForm1.Button3Click(Sender: TObject); var Peer: TPeer; S: string; begin Peer := TPeer.Create(nil); try Peer.PeerName := 'James'; Peer.PeerIP := '192.168.2.5'; Peer.PeerPort := 3256; Peer.Name := 'Peer' Peer.PeerName; S := ComponentToStringProc(Peer); Memo1.Lines.Add(S); finally Peer.Free; end; end; 字符串恢复为 Component: procedure TForm1.Button4Click(Sender: TObject); var APeer: TPeer; begin APeer := StringToComponentProc(Memo1.Lines.Text) as TPeer; Memo1.Lines.Clear; try Memo1.Lines.Add(APeer.Name); Memo1.Lines.Add(Apeer.PeerName); Memo1.Lines.Add(APeer.PeerIP); Memo1.Lines.Add(IntToStr(APeer.PeerPort)); finally APeer.Free; end; end; ------------------------------------------ 如果要把对象转换为 JSON 字符串,再转换回来,采用 REST.JSON 单元的 TJSON 的方法。这里可以对任何对象的 public 的属性进行序列化。也不需要注册对象类型。 对象转换为 JSON 字符串: procedure TForm1.Button1Click(Sender: TObject); var APeer: TPeerA; begin APeer := TPeerA.Create; //(nil); APeer.PeerName := 'James'; APeer.PeerIP := '192.168.9.0'; APeer.PeerPort := 234; try Memo1.Lines.Text := TJson.ObjectToJsonString(APeer); //REST.JSON 单元的 TJson 的方法。它序列化一个 Class 的 public 属性。不需要是 TComponent 也不需要是 published. finally APeer.Free; end; end; JSON字符串转换为对象: procedure TForm1.Button2Click(Sender: TObject); var S: string; APeer: TPeerA; begin S := Memo1.Lines.Text; APeer := TJson.JsonToObject try //Memo1.Lines.Add(APeer.Name); Memo1.Lines.Add(Apeer.PeerName); Memo1.Lines.Add(APeer.PeerIP); Memo1.Lines.Add(IntToStr(APeer.PeerPort)); finally APeer.Free; end; end; |
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
|
herbert2
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:58 回覆:640 積分:894 註冊:2004-04-16 發送簡訊給我 |
|
pcplayer99
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
很多用处。
比如,你有很多 parameters 在你的程式里面,如何组织?最简单的办法是用一个 Object,把这些 Parameters 当作这个 Object 的 Porperty。这样一来,你的 code 里面,任何需要这个 Parameter 的地方,你可以写: MySQLConnectionStr := MyObj.MyConnectionParameter; 类似这种写法。当你需要把一组很多个 Parameter 保存到 File 里面,下次程式启动时再用,一个办法是保存为 INI,一条一条地去写 MyIni.WriteString(); MyIni.WriteInteger(); 有多少条 Parameter 就写多少条。另一个办法就是直接把这个 Object 变成 string 写入 File,下次程式启动再从这个 File 加载到 Object 里面。 更进一步,如果你想通过网络来传递这个 Object 到网络另外一边的程式.............. |
GrandRURU
站務副站長 ![]() ![]() ![]() ![]() ![]() ![]() 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
受教了,謝謝你的分享!
===================引 用 pcplayer99 文 章=================== 很多用处。 比如,你有很多 parameters 在你的程式里面,如何组织?最简单的办法是用一个 Object,把这些 Parameters 当作这个 Object 的 Porperty。这样一来,你的 code 里面,任何需要这个 Parameter 的地方,你可以写: MySQLConnectionStr := MyObj.MyConnectionParameter; 类似这种写法。当你需要把一组很多个 Parameter 保存到 File 里面,下次程式启动时再用,一个办法是保存为 INI,一条一条地去写 MyIni.WriteString(); MyIni.WriteInteger(); 有多少条 Parameter 就写多少条。另一个办法就是直接把这个 Object 变成 string 写入 File,下次程式启动再从这个 File 加载到 Object 里面。 更进一步,如果你想通过网络来传递这个 Object 到网络另外一边的程式.............. |
pcplayer99
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |