1. HxD Hex Editor 1.6.1 (328 fois)
2. Open Office 2.2.1 (294 fois)
3. Delphi 6 (253 fois)
4. Windows Live Messenger (175 fois)
5. FireFox 2.0.0.12 (135 fois)
03 Sept 2008
Google Chrome : le navigateur 100 % Made In Google... ou presque !
28 Août 2008
Internet Explorer 8 : toutes les nouveautés du navigateur
18 Août 2008
Windows 7 : tout savoir sur le prochain système de Microsoft
13 Août 2008
The Pirate Bay censuré en Italie - L'arrêt de mort du réseau P2P ?
11 Août 2008
Hop : le nouveau téléphone jetable à 15€
Google : le maître des noms de domaines
La nouvelle version de GMail en images !
Barème de rémunération pour les disques durs multimédias
Afficher la date et heure du jour
Alignement de séquences d'ADN
TatNum : gestion des images avec Qt
À votre tour, devenez partenaire de mx-dev.net.
Vous êtes ici : Accueil › Delphi › Tutoriaux › Enregistrer une chaîne dans un TStream ou descendant
Auteur : Flo
Catégorie : Manipulation de fichiers
Niveau : Expert
Posté le : 23 Mai 2007 à 15h32
I.Introduction
Plus je lis de codes sources, plus je me rend compte que quasiment personne ne sait réellement écrire une chaîne dans un flux (=stream).
Enfin écrire, ça va à peu près (disons on croit qu'on y arrive), mais pour relire, c'est une autre histoire !
On a le droit à tout : PChar() , buffer de grande taille, et compagnie.
Alors que la solution est si simple:
Il suffit d'écrire la longueur de la chaîne et ensuite d'écrire la chaîne elle-même. Comme ça, pour charger, pas de soucis.
Attention quand même au petit piège dû au ref-counting de Delphi.
II.Code
Pour écrire une chaîne dans un flux (nécessite Classes dans les uses):
procedure WriteString(Fs: TStream; const S: string); var L: Integer; begin L := Length(S); Fs.WriteBuffer(L, SizeOf(Integer)); Fs.WriteBuffer(S[1], L); end;
Avouez que c'est simple.
Le code pour charger serait donc:
function ReadString(Fs: TStream): string; var L: Integer; begin Fs.ReadBuffer(L, SizeOf(Integer)); SetLength(Result, L); Fs.ReadBuffer(Result[1], L); end;
Et c'est simpliste ici aussi.
III.Commentaires
Alors: pourquoi personne n'y arrive ?
J'ai remarqué plusieurs pièges:
Il ne faut pas oublier d'écrire la taille de la chaîne sinon pour recharger, ça va être dur.
Il faut bien évidemment écrire la taille AVANT la chaîne elle même (pensez à la relecture ...)
Il faut écrire et charger S[1] et non pas S tout court. La raison ? Delphi alloue 8 octets de mémoire en plus pour contenir le compteur de références et la longueur de la chaîne. Pointer(S) ne pointe donc pas sur la chaîne mais sur le compteur. Pointer(S[1]) pointe, quant à lui, réellement à l'adresse mémoire voulue, c'est à dire celle du premier caractère.
Il faut penser à allouer la variable de réception (ici Result) de la chaîne avec SetLength(). Sinon, c'est la violation d'accès qui vous court derrière.
IV.Conclusion
Je pense donc qu'écrire une chaîne est simple mais il faut quand même savoir le faire correctement ... surtout si on veut pouvoir la relire !
De même, il est possible de créer une nouvelle classe, nommée par exemple TExFileStream qui contiendrait deux méthodes, respectivement pour lire et écrire une chaîne.
Pour vous éviter ce travail, je l'ai fait à votre place. Ainsi, vous trouverez la classe TExFileStream contenant ces méthodes sur la source EXSTREAM.