JSON 之 SuperObject(8): 关于乱码的几种情况 - 向 Henri Gourvest 大师报告

时间:2022-07-08 13:58:32

这几天学习 JSON - SuperObject, 非常幸运地得到了其作者 Henri Gourvest 大师的同步指点! (Henri 大师也是 DSPack 和 GDI+ 头文件的作者; 大师是法国人, 竟能用中文给我回复, 没想到!).

学习中发现 SuperObject 有些地方对中文(或者说 Unicode)支持不是所期望的, 现在专贴提出来供大师鉴别.

以下例子都会出现乱码, 虽然都可以有变通的方案, 但如果不乱码就太好了!


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses SuperObject;

procedure TForm1.Button1Click(Sender: TObject);
var
  jo: ISuperObject;
  stream: TStream;
begin
  stream := TMemoryStream.Create;

  jo := SO('{"Language" : "简体中文"}');
  jo.SaveTo(stream, False, False);

  stream.Position := ;
  Memo1.Lines.LoadFromStream(stream); // {"Language":"€S-?}

  stream.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
const
  FilePath = 'C:\Temp\Test.txt';
var
  jo: ISuperObject;
begin
  jo := SO('{"Language" : "简体中文"}');
  jo.SaveTo(FilePath, False, False);

  with TStringList.Create do
  begin
    LoadFromFile(FilePath);
    ShowMessage(Text);      // {"Language":"€S-?}
    Free;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  jo: ISuperObject;
  stream: TStream;
begin
  stream := TStringStream.Create('{"Language" : "简体中文"}');

  jo := TSuperObject.ParseStream(stream);
  ShowMessage(jo.AsJSon(False, False));   // {"Language":"¼òÌåÖÐÎÄ"}

  stream.Free;
end;

procedure TForm1.Button4Click(Sender: TObject);
const
  FilePath = 'C:\Temp\Test.txt';
var
  jo: ISuperObject;
begin
  with TStringList.Create do
  begin
    Add('{"Language" : "简体中文"}');
    SaveToFile(FilePath);
    Free;
  end;

  jo := TSuperObject.ParseFile(FilePath);
  ShowMessage(jo.AsJSon(False, False));   // {"Language":"¼òÌåÖÐÎÄ"}
end;

end.

下面是以上问题的暂时的变通方案:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses SuperObject;

procedure TForm1.Button1Click(Sender: TObject);
var
  jo: ISuperObject;
  stream: TStream;
begin
  stream := TMemoryStream.Create;

  jo := SO('{"Language" : "简体中文"}');
  jo.SaveTo(stream, False, True);

  stream.Position := ;
  Memo1.Lines.LoadFromStream(stream); // {"Language":"\u7b80\u4f53\u4e2d\u6587"}

  stream.Position := ;
  jo := TSuperObject.ParseStream(stream);
  ShowMessage(jo.AsString);           //{"Language" : "简体中文"}

  stream.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
const
  FilePath = 'C:\Temp\Test.txt';
var
  jo: ISuperObject;
begin
  jo := SO('{"Language" : "简体中文"}');
  jo.SaveTo(FilePath, False, True);

  with TStringList.Create do
  begin
    LoadFromFile(FilePath);
    ShowMessage(Text);      // {"Language":"\u7b80\u4f53\u4e2d\u6587"}
    Free;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  jo: ISuperObject;
  stream: TStream;
begin
  stream := TStringStream.Create('{"Language":"\u7b80\u4f53\u4e2d\u6587"}');

  jo := TSuperObject.ParseStream(stream);
  ShowMessage(jo.AsJSon(False, False));   // {"Language" : "简体中文"}

  stream.Free;
end;

procedure TForm1.Button4Click(Sender: TObject);
const
  FilePath = 'C:\Temp\Test.txt';
var
  jo: ISuperObject;
begin
  with TStringList.Create do
  begin
    Add('{"Language" : "简体中文"}');
    SaveToFile(FilePath);
    Free;
  end;

  Memo1.Lines.LoadFromFile(FilePath);
  jo := SO(Memo1.Text);
//  jo := TSuperObject.ParseFile(FilePath);
  ShowMessage(jo.AsJSon(False, False));   // {"Language" : "简体中文"}
end;

end.