从TStringStream读取数据字符串

时间:2016-09-13 17:14:22

标签: delphi delphi-xe8

我在不同的操作系统区域语言中遇到TStringStream编码问题。

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

但现在我在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;
  ...

1 个答案:

答案 0 :(得分:5)

您无法将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);