Delphi 分配给TStringList时丢失数据的字符串
我有这个方法,Delphi 分配给TStringList时丢失数据的字符串,delphi,string,unicode,delphi-2009,char,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
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是从,第121行已从更改
{$ifndefunicode}
到
{$ifdef UNICODE}
让它编译
无论如何,如果我使用fVar变量,我可以调用ZDecompressStr,但是一旦我将它移动到stringlist或memo,它似乎会丢失这6个字节的数据。。。。如果我尝试在s.text变量上使用ZDecompressStr,它会失败,并出现缓冲区错误。这可能是转换-TStringList。text属性是一个属性,而不是变量。您正在以一种有点危险的方式使用它,因为TStringList中有一些文本处理。您没有理由必须更改ZLibEx.pas的第121行;它适用于所有版本的Delphi,包括Delphi 2009。应仅为Delphi 2009定义
UNICODE
符号,如果是,则应跳过RawByteString
、UnicodeString
和UnicodeChar
的类型定义,因为它们已经是语言中的固有类型
ZCompressStr
将生成一个可能包含不可打印字符(包括空字节)的字符串。它将其结果存储在一个RawByteString
中,Delphi对此进行了专门处理
TStringList
,就像Delphi 2009中的其他东西一样,使用Unicode。其Text
属性的类型为UnicodeString
。当您将任何非UnicodeString值指定给UnicodeString时,您将得到一个转换,就像从API函数得到的一样。甚至RawByteString
也包含在该规则中。如果尚未将特定于代码页的字符串值分配给RawByteString
,则它将具有代码页0,即CP\u ACP
,这是系统的默认代码页
如果字符串实际上不包含根据系统代码页编码的字符,那么任何转换都会带来麻烦:垃圾输入,垃圾输出。特别是,不能保证您将获得相同数量的字符
,TStringList.Text
是一个属性。它有一个setter方法,可以将给定的字符串拆分为单独的行。当您读取属性时,它会再次将所有这些行重新合并为一个字符串。在设置属性时,TStrings.SetTextStr
(在Classes.pas中,如果您好奇的话)将在出现#0
、#10
或#13
时拆分行。即,空字符、换行符和回车符。当重新连接所有行时,它将使用其LineBreak
属性,该属性由全局sLineBreak
变量初始化。换行符也放在最后一个字符串之后,因此每一行都以LineBreak
结尾。因此,转换不一定是往返的
因此,有两件事需要从中学习:
TStrings
子体来保存不希望处理多个字符串的内容string
用作通用数据存储类型。仅用于实际文本。对于任意二进制数据的存储,首选t字节
,或t内存流
。使用您的示例,您可以压缩如下字符串:
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;
你为什么要用TStringList呢?如果你描述了你想要达到的目标,你就更有可能得到帮助你实现目标的答案。例如,tstringlist可能不是最好的工具(例如,一个字符串数组可能更好),当然,分配给tstringlist.text可能会引起一些混乱(tstringlist.add方法可能是您想要的)。但是,从你的问题很难判断,我之所以使用TStringList是因为我想在压缩数据后将其保存到文件中,为此我通常使用TStringList。这似乎是一个不-不,我一直在摆脱与D2009,但它已经抓住了我。好的一点。事实上,TStringList非常聪明,所以无论是使用DOS风格还是unix风格的终端,这都是一个非常好的答案。你的第一段-是的,这很奇怪,但是你有没有下载并尝试在他们的网站上使用ZlibEx,在我改变这一行之前,它根本不会编译,请看答案的重置是绝对正确的。我一直在使用TStrlingList,因为我想保存文件(TMemoryStream可以这样做),但我想通过互联网上的表单发布这些数据。我会把这一点写下来,修改一下我的问题。谢谢我一直很沮丧。如果能知道我的答案到底出了什么问题,那就太好了?