当前位置: 首页 > article >正文

把一个对象序列化为字符串,再反序列化回来

盒子论坛有人问如何把一个 TImage 的序列化后的字符串变成一个 TImage.

那么,首先我们来看看这个字符串是怎么来的,那就是:

如何把一个对象比如 Image1: TImage 序列化为字符串

看代码:

//序列化
function   ComponentToString(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;

假设 Form1 上面我有一个 Image12,并且加载了图片,然后,

调用上述代码:

procedure TForm5.Button4Click(Sender: TObject);
var
  S: string;
begin
  S := ComponentToString(Image12);

  Memo1.Lines.Text := S;
end;

获得的结果显示到 Memo1 里面了,如下:

object Image12: TImage
  Left = 488
  Top = 40
  Width = 105
  Height = 105
  Picture.Data = {
    0A544A504547496D6167654E1E0000FFD8FFE000104A46494600010101004800
    480000FFE100C04578696600004D4D002A000000080006011A00050000000100
    000056011B0005000000010000005E0128000300000001000200000131000200
    0000110000006601320002000000140000007887690004000000010000008C00
    000000000000480000000100000048000000017061696E742E6E657420352E30
    2E31330000323030393A30323A31392031313A30353A3432000003A001000300
    00000100010000A00200040000000100000270A003000400000001000001A900
    0000000000FFE107E9687474703A2F2F6E732E61646F62652E636F6D2F786170
    2F312E302F003C3F787061636B657420626567696E3D22EFBBBF222069643D22
    57354D304D7043656869487A7265537A4E54637A6B633964223F3E0D0A3C783A
    786D706D65746120786D6C6E733A783D2261646F62653A6E733A6D6574612F22
    20783A786D70746B3D2241646F626520584D5020436F726520342E312D633033
    362034362E3237363732302C204D6F6E2046656220313920323030372032323A
    34303A30382020202020202020223E0D0A20203C7264663A52444620786D6C6E
    733A7264663D22687474703A2F2F7777772E77332E6F72672F313939392F3032
    2F32322D7264662D73796E7461782D6E7323223E0D0A202020203C7264663A44
    65736372697074696F6E207264663A61626F75743D222220786D6C6E733A6463
    3D22687474703A2F2F7075726C2E6F72672F64632F656C656D656E74732F312E
    312F2220786D6C6E733A7861703D22687474703A2F2F6E732E61646F62652E63
    6F6D2F7861702F312E302F2220786D6C6E733A7861704D4D3D22687474703A2F
    2F6E732E61646F62652E636F6D2F7861702F312E302F6D6D2F2220786D6C6E73
    3A73745265663D22687474703A2F2F6E732E61646F62652E636F6D2F7861702F
    E41EBD4E4D15D1868C6F7B0E2DCB591F3D4B79AB3F882DE1D43529AE99409373
    392C016C753D4FE028AF739525748F3A3567CAF534F47D2AF75FB51ACEB3A9C9
    F62572A96D6D88CB727EF10063F0A2B96B4DC748E87651F7BE2361F53B3B4454
    D2F4E8ACE123EE040C4907BB1058FE268AE75152D65A972935A23FFFD9}
end

说明:以上序列化出来的字符串,我把图片二进制数据部分删除了很多,只保留了一部分,仅仅为了说明里面的字符串实际上是 HEX 数据。如果都保留,篇幅太大了。

如何把字符串反序列化为对象

上面序列化出来的字符串,如何使用代码,在运行期,加载字符串,变成一个 TImage 对象,并且呈现在界面上?

反序列化的代码:

//测试 TComponent 反序列化
function StringToComponent(Value: string): TComponent;
var
  StrStream:TStringStream;
  BinStream:   TMemoryStream;
begin
  RegisterClass(TImage);  //没有这个,会提示:Class TImage not found
  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;

调用上述函数,把 Image 从字符串反序列化回来,显示到一个 Panel1 上面:

procedure TForm5.Button3Click(Sender: TObject);
var
  AComponent: TComponent;
  S: string;
begin
  S := Memo1.Lines.Text;
  AComponent := StringToComponent(S);

  if (AComponent is TImage) then
  begin
    TImage(AComponent).Parent := Panel1;
    TImage(AComponent).Align := alClient;
  end;
end;

上述代码,在 Delphi 11 CE 版本上测试通过。

一个说明:

上述代码中,函数:StringToComponent 负责把字符串变成一个 TComponent 的对象,其中实际完成这个动作的代码是:BinStream.ReadComponent(nil);

但是,执行这一行,会有异常提示:Class TImage not found.

解决这个异常的办法就是,在执行这行代码之前,先注册 TImage:

RegisterClass(TImage);

当然,要在程序里面使用 TImage 还必须引用:Vcl.ExtCtrls

但是,仅仅是引用 Vcl.ExtCtrls 并不会使得 Class TImage not found 这个异常消失。

本文结束。

觉得本文有用的,点个赞吧!


http://www.kler.cn/a/399950.html

相关文章:

  • GNN初探
  • 【学习笔记】大模型调优(llms_tuning)
  • 【微软:多模态基础模型】(4)统一视觉模型
  • 什么是JSX?
  • AWTK VSCode 实时预览插件端口冲突的解决办法
  • 数据库的隔离机制---对MySQL 默认隔离级别的理解
  • cisco防火墙在内网通过外网域名进行访问的配置
  • 汽车与摩托车分类数据集
  • 【Flask+Gunicorn+Nginx】部署目标检测模型API完整解决方案
  • 【gitlab】gitlabrunner部署
  • 基于差分、粒子群算法下的TSP优化对比
  • YOLOv11融合针对小目标FFCA-YOPLO中的FEM模块及相关改进思路
  • Tailscale 自建 Derp 中转服务器
  • 【Mac】卸载JAVA、jdk
  • Day02_AJAX综合案例 (黑马笔记)
  • 在 CentOS 7 上安装 MinIO 的步骤
  • 【爬虫实战】抓取某站评论
  • 【论文笔记】SCOPE: Sign Language Contextual Processing with Embedding from LLMs
  • 代码随想录第三十四天
  • 输出比较简介
  • 来LeetCode练下思维吧
  • uniapp微信小程序转发跳转指定页面
  • git环境开发问题-处理
  • 【Oracle实战】文章导读
  • go的接口详解
  • C++小白实习日记——Day 2 TSCNS怎么读取当前时间