Il n'y a aucune raison que vous deviez modifier la ligne 121 de ZLibEx.pas; il est correct pour toutes les versions de Delphi, y compris Delphi 2009. Le symbole UNICODE
devrait seulement être défini pour Delphi 2009, et quand il est, les définitions de type pour RawByteString
, UnicodeString
, et UnicodeChar
devraient tous être ignorés, car ils sont déjà types intrinsèques dans la langue.
ZCompressStr
génère une chaîne pouvant contenir des caractères non imprimables, y compris des octets nuls. Il stocke son résultat dans un RawByteString
, que Delphi traite spécialement.
TStringList
, comme à peu près tout le reste dans Delphi 2009, utilise Unicode. Sa propriété Text
est du type UnicodeString
. Lorsque vous affectez n'importe quelle valeur non UnicodeString
à UnicodeString
, vous obtenez une conversion, à partir de la fonction API MultiByteToWideStr
. Même RawByteString
est inclus dans cette règle. Si vous n'avez pas attribué de valeur de chaîne spécifique à une page de codes à un RawByteString
, la page de codes 0, CP_ACP
, est la page de code par défaut de votre système.
Si la chaîne ne contient pas vraiment de caractères codés conformément à la page de codes système, toute conversion demande des problèmes: garbage in, garbage out. En particulier, il n'y a aucune garantie que vous obtiendrez le même nombre de caractères.
As Smok1 mentioned, TStringList.Text
est une propriété. Il a une méthode setter qui sépare la chaîne donnée en lignes séparées. Lorsque vous lisez la propriété, elle rejoint à nouveau toutes ces lignes dans une seule chaîne. Alors que mise la propriété, TStrings.SetTextStr
(à Classes.pas, si vous êtes curieux) se partageront la ligne à tout événement de #0
, #10
ou #13
. C'est-à-dire, les caractères nuls, les sauts de ligne et les retours chariot. En rejoignant toutes les lignes, il utilisera sa propriété LineBreak
, qui est initialisée avec la variable globale sLineBreak
. Un saut de ligne est également placé après la dernière chaîne, donc chaque ligne se termine par LineBreak
. Par conséquent, la conversion ne sera pas nécessairement aller-retour.
Donc, il y a deux choses à apprendre de cette:
- Ne pas traiter les données compressées sous forme de texte.
- N'utilisez pas les descendants
TStrings
pour stocker des objets dont vous ne souhaitez pas traiter plusieurs chaînes.
Un autre bon conseil: N'utilisez pas string
comme type générique de stockage de données. Utilisez-le uniquement pour le texte réel. Pour le stockage de données binaires arbitraires, préférez TBytes
ou TMemoryStream
. En utilisant votre exemple, vous pouvez compresser une chaîne comme ceci:
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;
Pourquoi utilisez-vous une TStringList? – stukelly
Si vous fournissez une description de ce que vous essayez d'accomplir, vous aurez plus de chances d'obtenir des réponses qui vous aideront à atteindre votre objectif. Par exemple, tstringlist n'est peut-être pas le meilleur outil (un tableau de chaînes pourrait être meilleur, par exemple) et certainement assigner à tstringlist.text peut causer une certaine confusion (la méthode tstringlist.add pourrait être ce que vous voulez). C'est difficile à dire, cependant, à partir de votre question. – Argalatyr
La raison pour laquelle j'utilise un TStringList est parce que je veux enregistrer les données dans le fichier une fois que je l'ai compressé - et pour cela j'ai généralement toujours utilisé TStringList. Il semble que ce soit un non non avec lequel je m'en suis sorti mais avec D2009 il m'a rattrapé. – Wizzard