我有一個{"data":[{"clientName":"Is Такой текст"}]}UTF-8 編碼的 JSON 檔案,我正在嘗試clientName使用該ShowMessage()函式查看標簽中的文本。
而不是普通文本,我得到“是奇怪的文本”。我知道問題出在編碼中,但我不明白如何解決它。
procedure TForm1.jsonTest;
var
JSONData, JSON: TJSONObject;
jArr: TJSONArray;
s: TStringList;
i, j: Integer;
jValue: TJSonValue;
JsonArray: TJSONArray;
jPair: TJSONPair;
begin
json := TJSONObject.Create;
s := TStringList.Create;
try
S.LoadFromFile('clientOrders.json');
text := S.Text;
JSON := TJSONObject.ParseJSONValue(BytesOf(text),0) as TJSONObject;
if JSON <> nil then
begin
jPair := JSON.Get(0);
jArr := jPair.JsonValue as TJSONArray;
for I := 0 to jArr.Size-1 do
begin
JSONData := jArr.Get(I) as TJSONObject;
for j := 0 to JSONData.Size - 1 do
begin
ShowMessage(JSONData.Get(j).JsonValue.ToString);
end;
end;
end
else
raise Exception.Create('This is not a JSON');
finally
json.Free;
s.Free;
jValue.Free;
end;
end;
uj5u.com熱心網友回復:
假設您在 Windows 上運行此代碼,那么問題有兩個方面:
你沒有告訴
TStringList.LoadFromFile()檔案的編碼是什么。因此,除非檔案以 UTF-8 BOM 開頭(不太可能使用 JSON 檔案),否則它將被解碼為 ANSI,而不是 UTF-8,從而破壞任何非 ASCII 字符。您正在將解碼后的文本轉換回位元組而不指定編碼。您正在使用的多載
ParseJSONValue()需要 UTF-8 編碼位元組,但BytesOf()會編碼為 ANSI,而不是 UTF-8,從而進一步破壞非 ASCII 字符。
這就是您從 JSON 中獲取垃圾文本的原因。
您的代碼也存在其他問題。即,由于您對 initlal 管理不善,導致記憶體泄漏和雙重釋放TJSONObject。
試試這個。
procedure TForm1.jsonTest;
var
JSONData, JSON: TJSONObject;
jArr: TJSONArray;
s: TStringList;
i, j: Integer;
jValue: TJSonValue;
data: string;
begin
s := TStringList.Create;
try
s.LoadFromFile('clientOrders.json', TEncoding.UTF8);
data := s.Text;
finally
s.Free;
end;
{ Alternatively:
data := IOUtils.TFile.ReadAllText('clientOrders.json', TEncoding.UTF8);
}
jValue := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(data), 0);
if jValue = nil then
raise Exception.Create('This is not a JSON');
try
JSON := jValue as TJSONObject;
jArr := JSON.Get(0).JsonValue as TJSONArray;
for I := 0 to jArr.Size-1 do
begin
JSONData := jArr.Get(I) as TJSONObject;
for j := 0 to JSONData.Size - 1 do
begin
ShowMessage(JSONData.Get(j).JsonValue.ToString);
end;
end;
end;
finally
jValue.Free;
end;
end;
Alternatively, don't decode the file bytes into a string just to convert them back into bytes, just load them as-is into ParseJSONValue(), eg:
procedure TForm1.jsonTest;
var
...
jValue: TJSonValue;
data: TBytesStream;
begin
data := TBytesStream.Create;
try
data.LoadFromFile('clientOrders.json');
jValue := TJSONObject.ParseJSONValue(data.Bytes, 0);
...
finally
data.Free;
end;
end;
Or:
procedure TForm1.jsonTest;
var
...
jValue: TJSonValue;
data: TBytes;
begin
data := IOUtils.TFile.ReadAllBytes('clientOrders.json');
jValue := TJSONObject.ParseJSONValue(data, 0);
...
end;
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/438620.html
