分配给TStringList时丢失数据的字符串

时间:2009-08-29 12:14:18

标签: delphi string unicode delphi-2009 char

我有这个方法,

var
s : TStringList;
fVar : string;
begin
s := TStringList.Create;
fVar := ZCompressStr('text');

ShowMessage( IntToStr(length(fVar) * SizeOf(Char)) );
//24

s.text := fVar;  

ShowMessage( IntToStr( length(s.text) * SizeOf(Char)) );
//18
end;

ZCompressStr来自http://www.base2ti.com/zlib.htm,第121行改为 {$ ifndef UNICODE} 至 {$ ifdef UNICODE} 使它编译。<​​/ p>

无论如何,如果我使用fVar变量,我可以调用ZDecompressStr,但是一旦我将它移动到字符串列表或备忘录,它似乎松开了那6个字节的数据....如果我尝试在s上使用ZDecompressStr .text var因缓冲区错误而失败。

2 个答案:

答案 0 :(得分:14)

您没有理由不得不更改 ZLibEx.pas 的第121行;它适用于所有版本的Delphi,包括Delphi 2009. UNICODE符号应为Delphi 2009定义,如果是,RawByteString的类型定义,应该跳过UnicodeStringUnicodeChar,因为它们已经是语言中的内在类型。

ZCompressStr将生成一个字符串,该字符串可能包含不可打印的字符,包括空字节。它将结果存储在RawByteString中,Delphi专门处理它。

TStringList,就像Delphi 2009中的其他所有内容一样,使用Unicode。其Text属性的类型为UnicodeString。当您将任何UnicodeString值分配给UnicodeString时,您会获得转换,例如MultiByteToWideStr API函数。即使RawByteString也包含在该规则中。如果您尚未将特定于代码页的字符串值分配给RawByteString,那么它将具有代码页0,即CP_ACP,即系统的默认代码页。

如果字符串实际上不包含根据系统代码页编码的字符,那么任何转换都会出现问题:垃圾进入,垃​​圾进出。特别是,不能保证您将获得相同数量的字符。

As Smok1 mentionedTStringList.Text是一个属性。它有一个setter方法,将给定的字符串拆分为单独的行。当您读取属性时,它会再次将所有这些行重新连接成一个字符串。当设置属性时,TStrings.SetTextStr(在 Classes.pas 中,如果您感到好奇)会在#0出现任意一行时拆分该行, #10#13。也就是说,空字符,换行符和回车符。重新连接所有行时,它将使用其LineBreak属性,该属性使用全局sLineBreak变量初始化。换行符也放在最后一个字符串之后,因此每一行都以LineBreak结尾。因此,转换不一定是往返。

因此,有两点需要从中学到:

  1. 不要将压缩数据视为文本。
  2. 请勿使用TStrings个后代来保存您不想处理多个字符串的内容。
  3. 另一个好建议:不要将string用作通用数据存储类型。仅用于实际文本。要存储任意二进制数据,请选择TBytesTMemoryStream。使用您的示例,您可以压缩这样的字符串:

    var
      ss: TStream;
      ms: TMemoryStream;
    begin
      ss := TStringStream.Create('text');
      try
        ms := TMemoryStream.Create;
        try
          ShowMessage(IntToStr(ss.Size));
          ZCompressStream(ss, ms);
          ShowMessage(IntToStr(ms.Size));
        finally
          ms.Free;
        end;
      finally
        ss.Free;
      end;
    end;
    

答案 1 :(得分:2)

这可能是转换--TStringList.Text属性是属性,而不是变量。您使用它有点危险,因为在TStringList中有一些Text处理。