TQJsonOutputChannel 的主要作用是用来快速写入大型的 JSON 数据到文件中,所以整体是面向写入过程设计的,不要试图用它来控制内容的修改。
假设我们要将数据内容写入到目标数据流 AStream 中:
第一步:我们需要定义一个 IQJsonStreamEncoder 的实例,它是一个结构体,所以直接在栈上定义这个变量即可。
1 2 |
var AWriter: IQJsonStreamEncoder; |
第二步:创建实例并建立与目标数据流的关联:
1 |
AWriter := TQJsonOutputChannel.CreateEncoder(teUtf8, AStream); |
还有一个最大层数限制,默认为32,可以通过第三个参数修改。
第三步:开始按照正常的规则写入 JSON 数据。
- 调用 BeginArray 开始一个数组定义,它必需在元素输出完成后,对应一个 EndArray 调用来标志此数组输出结束。也可以使用 WriteArray 来定义数组。
- 调用 BeginObject 开始一个对象定义,它必需在子结点输出完成后,对应一个 EndObject 调用来标志此对象输出结束。也可以使用 WriteObject 来定义对象。
- 调用 WriteElement 方法写入数组元素的值
- 调用 WriteChild 方法写入普通类型的值
第四步:已经完事了,补充一点吧,这个写入的JSON是以压缩格式写入的,没有加入缩进支持。可以用TQJsonInputChannel 来顺序读取。
最后,来一段示例代码,Show you my code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
procedure TForm2.SpeedButton1Click(Sender: TObject); var AStream: TMemoryStream; AJson: TQJson; I: Integer; AWriter: IQJsonStreamEncoder; begin AJson := AcquireJson; AStream := TMemoryStream.Create; try AJson.Add('O').Add('01'); AJson.AddArray('A'); AWriter := TQJsonOutputChannel.CreateEncoder(teUtf8, AStream); AWriter.BeginArray(''); for I := 0 to 9 do begin AWriter.BeginObject(''); AWriter.WriteChild('Ident', 'Json Stream Writer'); AWriter.WriteChild('IntValue', I); AWriter.WriteChild('FloatValue', Double(1.333 * I)); AWriter.WriteChild('BoolValue', (I mod 2) = 1); AWriter.WriteChild('NullValue'); AWriter.WriteChild('DateTime', Now); AJson.ForcePath('O.01').AsString := I.ToString; AWriter.WriteChild('Json', AJson); AWriter.EndObject; end; AWriter.EndArray; AStream.Position := 0; repeat AJson.LoadFromStream(AStream, teUtf8); ShowMessage(AJson.Encode(true)); until AStream.Position = AStream.Size; finally ReleaseJson(AJson); FreeAndNil(AStream); end; end; procedure TForm2.SpeedButton2Click(Sender: TObject); var AStream: TMemoryStream; AJson: TQJson; I: Integer; AWriter: IQJsonStreamEncoder; begin AJson := AcquireJson; AStream := TMemoryStream.Create; try AJson.Add('O').Add('01'); AJson.AddArray('A'); AWriter := TQJsonOutputChannel.CreateEncoder(teUtf8, AStream); AWriter.WriteArray('', procedure(AParent: IQJsonArrayEncoder) var I: Integer; begin for I := 0 to 9 do begin AParent.WriteObject( procedure(AObjParent: IQJsonObjectEncoder) begin AObjParent.Write('Ident', 'Json Stream Writer'); AObjParent.Write('IntValue', I); AObjParent.Write('FloatValue', Double(1.333 * I)); AObjParent.Write('BoolValue', (I mod 2) = 1); AObjParent.Write('NullValue'); AObjParent.Write('DateTime', Now); AJson.ForcePath('O.01').AsString := I.ToString; AObjParent.Write('Json', AJson); end); end end); AStream.Position := 0; repeat AJson.LoadFromStream(AStream, teUtf8); ShowMessage(AJson.Encode(true)); until AStream.Position = AStream.Size; finally ReleaseJson(AJson); FreeAndNil(AStream); end; end; |