DELPHI 关于内存数据与 JSON

摘要:
Delphi与内存数据的总结与回顾:1、普通类型变量:储存一个数据。System.JSON是官方的;这省去很多麻烦,这也是我考虑它的主要原因。如果不是太复杂的json应用,优先考虑System.JSON吧;如果需要更多功能,SuperObject会更理想。1分钟了解System.JSON:其中的类不少,主要用到的有:TJSONObject、TJSONArray。

正在用 WebBroker 写一个小网站,感受颇多:
1、如果是写一个小东西,应该先考虑下 WebBroker,因为它是分分钟即可上手的。
2、如果要写一个大东西,或许也应该考虑下 WebBroker,因为相比其他它有着最高的灵活度(但这只是想像,因为我只是写了一个小东西)。
3、Delphi 3 就有了 WebBroker,可惜现在才开始使用它;随着“服务器”与“网页程序”的普及,WebBroker 应该会被更多地提起。
期间用到了 json, 所以有了这篇博文。


Delphi 与内存数据的总结与回顾:
1、普通类型变量:储存一个数据。
2、数组:储存一组同类型的数据。
3、结构体:储存一组不同类型的数据;现在的结构体越来越复杂了,还可以操作这些个数据,越来越像“类”了。
4、“键值”对:我一般使用 TStringList,并常常用它代替 ini 文件类;同类还有 THashedStringList、TStringHash。
5、分类的 “键值”对:TMemIniFile、TIniFile; 另外还有人用 sqlite 做了一个可以储存二进制数据的 ini 文件类(忘了名了),我试过,非常好用(在官方示例中)。
6、内存数据表:现在应该首选 TFDMemTable 了(之前是 TClientDataSet)。
7、数据库级别的内存(或文件)数据:SqLite。
8、内存多叉树:JSON(或 XML);之前一直使用 SuperObject,以后会使用 System.JSON 更多些。


System.JSON?还是 SuperObject?
System.JSON 是官方的;这省去很多麻烦,这也是我考虑它的主要原因。
System.JSON “读写文件” 与 “格式化” 等功能,都有的功能也不如 SuperObject 方便。
System.JSON 主要考虑的是:从服务器生成 json,然后传输到客户端(特别是给 JavaScript 使用),不像 SuperObject 大而全。
如果不是太复杂的 json 应用,优先考虑 System.JSON 吧;如果需要更多功能,SuperObject 会更理想。


1 分钟了解 System.JSON:
其中的类不少,主要用到的有:TJSONObject、TJSONArray。


uses System.JSON;

//TJSONObject
procedure TForm1.Button1Click(Sender: TObject);
var
 j: TJSONObject;
begin
 j := TJSONObject.Create;
 j.AddPair('aa', '111');
 j.AddPair('bb', '222');

 //输出字符串
 Memo1.Text := j.ToString; //结果:{"aa":"111","bb":"222"}
  {ToJSON 与 ToString 结果相同,但应尽量使用 ToString 而不是 ToJSON;因为 ToJSON 也是调用 ToString 并且还要重新分配内存}

 j.Free;
end;

//TJSONArray
procedure TForm1.Button2Click(Sender: TObject);
var
 a: TJSONArray;
begin
 a := TJSONArray.Create;
 a.Add(1); //TJSONArray 不像传统的数组,它可以接受几种不同类型的值;这应该算是对 Delphi 数组功能的扩充吧。
 a.Add(2);
 a.Add('aaa');
 a.Add('bbb');

 Memo1.Text := a.ToString; //结果:[1,2,"aaa","bbb"]

 a.Free;
end;

//当 TJSONObject 嵌套其他对象时
procedure TForm1.Button3Click(Sender: TObject);
var
 j: TJSONObject;
 a: TJSONArray;
begin
 j := TJSONObject.Create;
 a := TJSONArray.Create('aaa', 'bbb'); //可以使用两个值初始化
 a.Add(1);
 a.Add(2);

 j.AddPair('arr', a);

 Memo1.Text := j.ToString; //结果:{"arr":["aaa","bbb",1,2]}

// a.Free; {千万不要释放其内部对象,它的父对象会自动释放它}
 j.Free;
end;

//变通上例
procedure TForm1.Button4Click(Sender: TObject);
var
 j: TJSONObject;
begin
 j := TJSONObject.Create;

 j.AddPair('arr', TJSONArray.Create);

 with j.Values['arr'] as TJSONArray do
 begin
  Add('aaa');
  Add('bbb');
  Add(1);
  Add(2);
 end;

 Memo1.Text := j.ToString; //结果:{"arr":["aaa","bbb",1,2]}
 j.Free;
end;

//再变通
procedure TForm1.Button5Click(Sender: TObject);
var
 j: TJSONObject;
 a: TJSONArray;
begin
 j := TJSONObject.Create;

 j.AddPair('arr', TJSONArray.Create);

 a := TJSONArray(j.Values['arr']);
 a.Add('aaa');
 a.Add('bbb');
 a.Add(1);
 a.Add(2);

 Memo1.Text := j.ToString; //结果:{"arr":["aaa","bbb",1,2]}
 j.Free;
end;

//添加其他类型的数
procedure TForm1.Button6Click(Sender: TObject);
var
 j: TJSONObject;
 a: TJSONArray;
begin
 j := TJSONObject.Create;
 j.AddPair('数值', TJSONNumber.Create(3.1415926));
 j.AddPair('布尔真', TJSONTrue.Create);
 j.AddPair('布尔假', TJSONFalse.Create);
 j.AddPair('空值', TJSONNull.Create);

 Memo1.Text := j.ToString; //结果:{"数值":3.1415926,"布尔真":true,"布尔假":false,"空值":null}
 j.Free;
end;

//读取
procedure TForm1.Button7Click(Sender: TObject);
var
 j: TJSONObject;
 str: string;
 num: Integer;
 arr1,arr2: string;
begin
 j := TJSONObject.Create;
 j.AddPair('str', '111');
 j.AddPair('num', TJSONNumber.Create(222));
 j.AddPair('arr', TJSONArray.Create('arr1', 'arr2'));

 Memo1.Text := j.ToString; //结果:{"str":"111","num":222,"arr":["arr1","arr2"]}

 //JSON 是一组”键值对“,其中的”值“还有可能是”键值对“;
 //所以 System.JSON 用 TJSONValue 来表示值类型,它是所有值类型的父类,当然也是 TJSONObject 的父类。

 str := j.Values['str'].Value;       //Values[] 调用的是 GetValue(), 更喜欢直接用后者
 num := j.GetValue('num').Value.ToInteger;

 arr1 := TJSONArray(j.GetValue('arr')).Items[0].Value;
 arr2 := TJSONArray(j.GetValue('arr')).Items[1].Value;

 Memo1.Lines.Add(Format('%s, %d, %s, %s', [str, num, arr1, arr2])); //111, 222, arr1, arr2

 j.Free;
end;

//遍历
procedure TForm1.Button8Click(Sender: TObject);
var
 j: TJSONObject;
 p: TJSONPair;
 v: TJSONValue;
 i: Integer;
 a: TJSONArray;
begin
 j := TJSONObject.Create;
 j.AddPair('aa', '111');
 j.AddPair('bb', '222');
 j.AddPair('arr', TJSONArray.Create('arr1', 'arr2'));

 //集合遍历 TJSONObject
 for p in j do
  Memo1.Lines.Add(p.ToString); //"aa":"111" \ "bb":"222" \ "arr":["arr1","arr2"]

 //索引遍历 TJSONObject, 这里的 Get 函数已不提倡使用了
 for i := 0 to j.Count - 1 do
  Memo1.Lines.Add(j.Get(i).ToString); //"aa":"111" \ "bb":"222" \ "arr":["arr1","arr2"]

 //集合遍历 TJSONArray
 for v in j.Values['arr'] as TJSONArray do
  Memo1.Lines.Add(v.Value); //arr1 \ arr2

 //索引遍历 TJSONArray
 a := j.Values['arr'] as TJSONArray;
 for i := 0 to a.Count - 1 do
  Memo1.Lines.Add(a.Items[i].Value); //arr1 \ arr2
 j.Free;
end;

//存取到文件
procedure TForm1.Button9Click(Sender: TObject);
var
 j1,j2: TJSONObject;
begin
 //随便虚拟些数据
 j1 := TJSONObject.Create(TJSONPair.Create('aaa', '111'));
 j1.AddPair('bbb', j1.Clone as TJSONValue);

 ChDir('c:	emp');

 //写入文件
 with TStringList.Create do
 begin
  Add(j1.ToString);
  SaveToFile('JsonTest.txt', TEncoding.UTF8); //结果:{"aaa":"111","bbb":{"aaa":"111"}}
  Free;
 end;
 j1.Free;

 //从文件读取
 with TStringList.Create do
 begin
  LoadFromFile('JsonTest.txt', TEncoding.UTF8);
  j2 := TJSONObject.ParseJSONValue(Text) as TJSONObject;
  Free;
 end;

 Memo1.Text := j2.ToString; //结果:{"aaa":"111","bbb":{"aaa":"111"}}
 j2.Free;
end;

//修改、删除
procedure TForm1.Button10Click(Sender: TObject);
var
 j: TJSONObject;
begin
 j := TJSONObject.Create;
 j.AddPair('aaa', '111');
 j.AddPair('bbb', '222');
 j.AddPair('ccc', '333');

 //修改
 j.Get('aaa').JsonValue := TJSONString.Create('11111'); //TJSONPair 的 JsonString、JsonValue 分别是 键、值
// j.Pairs[0].JsonValue := TJSONString.Create('11111');

 //删除
 j.RemovePair('bbb');

 Memo1.Lines.Add(j.ToString); //结果:{"aaa":"11111","ccc":"333"}

 j.Free;
end;

//根据路径添加数组的函数:
procedure CreateJSONPathArr(aJson: TJSONObject; const aPath: string; jArr: TJSONArray);
var
 arr: TArray<string>;
 path: string;
 i: Integer;
begin
 arr := aPath.Split(['.'], ExcludeEmpty);
 for i := 0 to Length(arr) - 1 do
 begin
  if not aJson.TryGetValue(arr[i], aJson) then
  begin
   if i = Length(arr) - 1 then
    aJson.AddPair(arr[i], jArr)
   else begin
    aJson.AddPair(arr[i], TJSONObject.Create);
    aJson.TryGetValue(arr[i], aJson);
   end;
  end;
 end;
end;

//调用测试:
var
 j: TJSONObject;
 a: TJSONArray;
begin
 j := TJSONObject.Create;

 a := TJSONArray.Create('11', '22');
 CreateJSONPathArr(j, 'aaa.bbb.ccc', a);

 a := TJSONArray.Create('33', '44');
 CreateJSONPathArr(j, 'aaa.bbb.ddd', a);

 j.Free;
end;

免责声明:文章转载自《DELPHI 关于内存数据与 JSON》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇cygwin配合NDK开发Android程序MSSQl分布式查询下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Delphi XE中类成员的访问权限(新增了strict private和strict protected,还有automated)

Delphi XE中类成员的访问权限共提供了6个关键词来用于限定访问权限:public、private、protected、published、automated strict private 、 strict protected其各自的含义为: 1. strict private:此区定义的字段或方法只能用于当前的类中。即T1中此区定义的成员只能在T1中...

Delphi 10.3.2 社区版的安装

1、去 https://www.embarcadero.com/cn/products/delphi/starter 下载安装程序 首先你要有一个embarcadero社区账号,国内线路下载有点慢,下载到了大约 127MB 左右的安装文件,如下图; 2、勾选“I agree …”; 3、点击<Options>按钮可以选择安装路径; 4、输...

leetcode编程框架——在IDE上模拟leetcode环境

1、为什么写这个为了用IDE!,这样不同的大题,复制粘贴就完事,真正帮你节约大把时间来思考题目。 import sys # 这里写解决问题的代码,和LeetCode就完全一样了 def solve(arr): pass if __name__ == '__main__': # 接收输入的逻辑,这里先把输入接收过来, 两种选择input()和sy...

Delphi 实现窗体自适应调整尺寸以适应不同屏幕分辩率的显示问题

给你一段代码,网上转的:unit uMyClassHelpers;//实现窗体自适应调整尺寸以适应不同屏幕分辩率的显示问题。//        陈小斌,2012年3月5日interfaceUses  SysUtils,Windows,Classes,Graphics, Controls,Forms,Dialogs, Math,typinfo;//  uMy...

UML建模三个工具: StarUML ,Telelogic TAU 和 Rose

UML建模软件目前用的主要有3种: 商业版本:Telelogic TAU 和 RationalRose开源版本:StarUML Telelogic TAU与Rational Rose的功能很强,但是需要买License。 StarUML就是希望能提供和TAU/Rose一样功能的开源版本。 目前使用起来还是不错的。 能熟练使用其中一个是软件设计人员的基本功...

delphi 对应 c# 的一些函数及类型的转换方法【原】

例一 实现目的:将字符串中每一个字符转成二进制(比如 'Data' 中的 D 转成 00100010 ,整个就是 00100010100001100010111010000110) 处理逻辑:string result = StrToByte("Data"); result结果是00100010100001100010111010000110   1、实际...