首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TStream到TStringList的unicode失败

TStream到TStringList的unicode失败
EN

Stack Overflow用户
提问于 2014-08-12 21:08:49
回答 1查看 3K关注 0票数 2

如下面代码的Test2所示,TStringList被转换为TStream,然后TStream被转换回TStringList。然而,在Delphi7中,Test2给出了与Test1相同的内容。在unicode中,Test2没有给出正确的结果。你能帮我提一下怎么回事吗?

代码语言:javascript
复制
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  Classes, SysUtils;

// http://stackoverflow.com/questions/732666
// Converting TMemoryStream to String in Delphi 2009
function MemoryStreamToString(M: TMemoryStream): string;
begin
  SetString(Result, PChar(M.Memory), M.Size div SizeOf(Char));
end;

procedure Test1;
var
  SrcList: TStrings;
  S: String;
  AStream: TStream;
begin
  SrcList := TStringList.Create;
  try
    with SrcList do
    begin
      Add('aa');
      Add('bb');
      Add('cc');
    end;

    S := SrcList.Text;

    AStream := TMemoryStream.Create;
    try
      // AStream.Write(S[1], Length(S));
      // AStream.Write(S[1], Length(S) * SizeOf(Char));
      AStream.Write(Pointer(S)^, Length(S) * SizeOf(Char));

      WriteLn(MemoryStreamToString(TMemoryStream(AStream)));
    finally
      AStream.Free;
    end;
  finally
    SrcList.Free;
  end;
end;

procedure Test2;
var
  SrcList: TStrings;
  S: String;
  AStream: TStream;
  DestList: TStringList;
  I: Integer;
begin
  SrcList := TStringList.Create;
  try
    with SrcList do
    begin
      Add('aa');
      Add('bb');
      Add('cc');
    end;

    S := SrcList.Text;

    AStream := TMemoryStream.Create;
    try
      // AStream.Write(S[1], Length(S));
      // AStream.Write(S[1], Length(S) * SizeOf(Char));
      AStream.Write(Pointer(S)^, Length(S) * SizeOf(Char));

      DestList := TStringList.Create;
      try
        AStream.Position := 0;
        DestList.LoadFromStream(AStream);

        WriteLn(DestList.Text);
      finally
        DestList.Free;
      end;
    finally
      AStream.Free;
    end;
  finally
    SrcList.Free;
  end;
end;

begin
  try
    Test1;
    Test2;
  except
    on E: Exception do
      WriteLn(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-12 21:18:16

Test1将原始String数据写入TMemoryStream中,然后按-is格式读取回String,因此在Delphi的所有版本中,所有内容都是正确匹配的。Test2在Delphi2007和更早的时候工作是出于类似的原因。

Test2在Delphi2009及以后的版本中失败,因为您没有考虑到TStrings.LoadFrom...() (和TStrings.SaveTo...())是德尔福的那些版本中的TEncoding-aware。您正在将UTF-16编码数据写入TMemoryStream,而前面没有BOM,然后您不会告诉LoadFromStream()该流是UTF-16编码的。它试图定位BOM,当它找不到BOM时,它使用TEncoding.Default (也称为8位Ansi)加载流(为了与遗留代码向后兼容)。

因此,在本例中,您需要在Delphi 2009及更高版本中加载流数据时指定流数据的适当编码:

代码语言:javascript
复制
DestList.LoadFromStream(AStream, TEncoding.Unicode);
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25274070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档