我有一个JSON文件,其编码的UTF-8字符串字段表示JPG内容:
"ImageData": "ÿØÿà\u0000\u0010JFIF\u0000\u0001\u0002\u0000\u0000d\u0000d\u0000\u0000
Run Code Online (Sandbox Code Playgroud)
我正在解析JSON并获取该值:
var imageString : string;
...
imageString:=jv.GetValue<string>('ImageData');
Run Code Online (Sandbox Code Playgroud)
但是我在解码字节并将它们保存到文件时遇到问题
选项1。 SaveBytesToFile(BytesOf(imageString),pathFile);
如您所见,标题不正确(应以ÿØÿà开头)
选项2。 SaveBytesToFile(TEncoding.UTF8.GetBytes(imageString),pathFile);
与选项1类似的问题
SaveBytesToFile的代码:
procedure SaveBytesToFile(const Data: TBytes; const FileName: string);
var
stream: TMemoryStream;
begin
stream := TMemoryStream.Create;
try
if length(data) > 0 then
stream.WriteBuffer(data[0], length(data));
stream.SaveToFile(FileName);
finally
stream.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
如何正确解码?
Rem*_*eau 10
JSON是纯文本格式,根本没有提供处理二进制数据的规定。为什么图像字节没有以兼容文本的格式编码,例如base64,base85,base91等?否则,请改用BSON(二进制JSON)或UBJSON(通用二进制JSON)之类的东西,它们都支持二进制数据。
在任何情况下,BytesOf()都会破坏字节,因为它使用用户的默认语言环境(通过TEncoding.Default,在非Windows平台上为UTF-8!),因此ASCII范围以外的字符将受到语言环境的解释,并且不会产生字节你需要。
在您的情况下,请确保JSON库将JSON文件解码为UTF-8,然后您可以简单地循环遍历所得的字符串(JSON库应为您将转义的序列解析为字符)并按原样截断字符到8位值。根本不执行任何类型的字符集转换。例如:
var
imageString : string;
imageBytes: TBytes;
i: Integer;
...
begin
...
imageString := jv.GetValue<string>('ImageData');
SetLength(imageBytes, Length(imageString));
for i := 0 to Length(imageString)-1 do begin
imageBytes[i] := Byte(imageString[i+1]);
end;
SaveBytesToFile(imageBytes, pathFile);
...
end;
Run Code Online (Sandbox Code Playgroud)
附带一提,您SaveBytesToFile()可以大大简化您的工作,而不会浪费内存来复制以下内容TBytes:
procedure SaveBytesToFile(const Data: TBytes; const FileName: string);
var
stream: TBytesStream;
begin
stream := TBytesStream.Create(Data);
try
stream.SaveToFile(FileName);
finally
stream.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
要么:
procedure SaveBytesToFile(const Data: TBytes; const FileName: string);
var
stream: TFileStream;
begin
stream := TFileStream.Create(FileName, fmCreate);
try
stream.WriteBuffer(PByte(Data)^, Length(Data));
finally
stream.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
要么:
uses
..., System.IOUtils;
procedure SaveBytesToFile(const Data: TBytes; const FileName: string);
begin
System.IOUtils.TFile.WriteAllBytes(FileName, Data);
end;
Run Code Online (Sandbox Code Playgroud)