从 TStringStream 中读取数据字符串

Reading the data string From TStringStream

我对 TStringStream 不同 OS 地区语言的编码有疑问。

我正在尝试传输图像数据。之前遇到问题,在另一个问题中解决了

但现在 TStringStream 本身存在编码问题。如果操作系统区域语言设置为英语,我会从 TStringStream.

获取损坏的数据

当我将语言更改为阿拉伯语时,数据正确显示。

我目前使用 Indy 对二进制数据进行编码,但在开始编码之前,如果区域编码未设置为阿拉伯语,来自 StringStream.DataString 的数据已经损坏。我尝试将 TEncoding.UTF8 添加到 TStringStream.Create(),但数据仍然从 StringStream.DataString 错误地出来。

function Encode64(const S: string; const ByteEncoding: IIdTextEncoding = nil): string;
begin
  Result := TIdEncoderMIME.EncodeString(S, ByteEncoding);
end;

function Decode64(const S: string; const ByteEncoding: IIdTextEncoding = nil): string;
begin
  Result := TIdDecoderMIME.DecodeString(S, ByteEncoding);
end;

StringStream := TStringStream.Create('');
try
  Jpg.Performance := jpBestSpeed;
  Jpg.ProgressiveEncoding := True;
  Jpg.ProgressiveDisplay := True;
  jpg.Assign(Image2.Picture.Bitmap);
  jpg.CompressionQuality := 25;
  jpg.Compress;
  jpg.SaveToStream(StringStream);
  StringImageData := StringStream.DataString; // the data here is corrupted when Os region is not set to arabic 
  strcams := '<[S:' + IntToStr(Length(StringImageData)) + 'B]>' + StringImageData;
  if length(strcams) < byt then begin
    Sendimgdata('IMGDATA123', Encode64(strcams, IndyTextEncoding_UTF8) + sep);
  end;
  ...

您不能首先将 JPG 保存为 TStringStream。您需要先对二进制数据进行编码,而不是先将其转换为字符串,这会破坏数据。使用 TMemoryStream 代替二进制数据:

MemoryStream := TMemoryStream.Create;
...
jpg.SaveToStream(MemoryStream);
MemoryStream.Position := 0;
StringImageData := TIdEncoderMIME.EncodeStream(MemoryStream);
...

如果你想在插入带有长度的文本后进行编码,你也必须使用 TMemoryStream:

procedure StringToStream(aStream: TStream; const aString: AnsiString);
begin
  aStream.Write(PAnsiChar(AString)^, Length(AString));
end;

...

JpegStream := TMemoryStream.Create;
jpg.SaveToStream(JpegStream);

CompleteStream := TMemoryStream.Create;
StringToStream(CompleteStream, '<[S:' + IntToStr(JpegStream.Size)+'B]>');

CompleteStream.CopyFrom(JpegStream, 0);
StringImageData := TIdEncoderMIME.EncodeStream(CompleteStream);