閒話:
正在用 WebBroker 寫一個小網站,感覺頗多:
一、若是是寫一個小東西,應該先考慮下 WebBroker,由於它是分分鐘便可上手的。
二、若是要寫一個大東西,或許也應該考慮下 WebBroker,由於相比其餘它有着最高的靈活度(但這只是想像,由於我只是寫了一個小東西)。
三、Delphi 3 就有了 WebBroker,惋惜如今纔開始使用它;隨着「服務器」與「網頁程序」的普及,WebBroker 應該會被更多地提起。
期間用到了 json, 因此有了這篇博文。
Delphi 與內存數據的總結與回顧:
一、普通類型變量:儲存一個數據。
二、數組:儲存一組同類型的數據。
三、結構體:儲存一組不一樣類型的數據;如今的結構體愈來愈複雜了,還能夠操做這些個數據,愈來愈像「類」了。
四、「鍵值」對:我通常使用 TStringList,並經常用它代替 ini 文件類;同類還有 THashedStringList、TStringHash。
五、分類的 「鍵值」對:TMemIniFile、TIniFile; 另外還有人用 sqlite 作了一個能夠儲存二進制數據的 ini 文件類(忘了名了),我試過,很是好用(在官方示例中)。
六、內存數據表:如今應該首選 TFDMemTable 了(以前是 TClientDataSet)。
七、數據庫級別的內存(或文件)數據:SqLite。
八、內存多叉樹: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:\temp');
//寫入文件
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;