INITIATION AU FICHIER DE SAUVEGARDE BINAIRE.

cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 - 21 juin 2006 à 11:28
beckerich Messages postés 302 Date d'inscription jeudi 29 septembre 2005 Statut Membre Dernière intervention 17 septembre 2013 - 14 mai 2012 à 14:09
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/38197-initiation-au-fichier-de-sauvegarde-binaire

beckerich Messages postés 302 Date d'inscription jeudi 29 septembre 2005 Statut Membre Dernière intervention 17 septembre 2013 2
14 mai 2012 à 14:09
Merci pour la qualité de vos sources.

Une question : dans TPersonne, Taille se rapporte au sexe ? ;-))

Luc.
hfr11 Messages postés 20 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 8 octobre 2019
18 déc. 2007 à 11:28
Merci... Bonne journée à tous, Patrice
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
18 déc. 2007 à 11:14
Si le code avait été mis à jour, il y aurait visible la liste des MAJ avec les dates.
hfr11 Messages postés 20 Date d'inscription mardi 17 décembre 2002 Statut Membre Dernière intervention 8 octobre 2019
18 déc. 2007 à 09:44
Bonjour,
Je ne suis pas très malin car je n'ai pas trouvé le lien pour poster ce message directement à l'attention des administrateurs du site...
Juste une petite remarque qui pourrait, je pense, améliorer encore le site :
L'exemple de ce développement en est une parfaite illustration.
Au cours de la lecture des commentaires, on trouve une série de suggestions appelant à améliorer le code proposé.
Il serait intéressant de pouvoir consulter la date du zip proposé afin de savoir avant téléchargement si le code a bénéficié ou pas de le suggestion proposée à une date "d", de savoir aussi dans certains cas si le code proposé a subi une modification par rapport à celui qu'on pourrait avoir déjà téléchargé antérieurement.
Je vous remercie tous ici car j'apprends énormément en vous lisant. Je ne suis qu'un petit développeur amateur qui a souvent besoin de se confectionner des outils sur mesure et très rapidement en tant que bête ingénieur système et j'avoue ici que vous m'avez déjà tiré plus d'une épine du pied. Bon courage et bonne continuation à tous, merci, Patrice
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
26 juil. 2006 à 17:45
Je me suis aperçu qu'avec Delphi7, on pouvait très bien sauvegarder directement une variable de type énuméré, sans passer par son indice. Cela dépend-il de la version de Delphi? J'aimerai bien le savoir avant de corriger mon code...

D'autre part, Debiars m'a fait remarquer qu'on pouvait sauvegarder un record globalement, sans le sauvegarder élément par élément, même s'il s'agit d'énumérés ou de String. Cela sera corrigé dès que possible. Merci à Debiars.
ThWilliam Messages postés 418 Date d'inscription mardi 3 janvier 2006 Statut Membre Dernière intervention 26 novembre 2013 4
30 juin 2006 à 16:48
Salut Caribensila,

Comme je n'ai jamais employé TFileStream (mais tjs les vieilles méthodes Pascal), je comptais prochainement le découvrir.
Et voilà que tu me sers ca sur un plateau d'argent !
Merci et bravo pour ta source.

Thierry

PS: je vais faire mes propres essais, j'aurai vraisemblablement des questions...
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
27 juin 2006 à 18:11
Je mets une source "StreamZip". Donnez moi votre avis...
Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
27 juin 2006 à 16:24
Il n'est pas possible de compresser des données au moment ou elles sont utiliser par un stream (Il s'agit d'un flux). Tes données si elles sont compressées le sont soit avant soit apres leurs "migrations". Les deux méthodes que tu cites doivent certainement réalisées une compression/décompression juste avant l'utilisation du stream.

Maintenant sache que les streams dérivent directement des blocks. Ce processus est déja optimisé : tu ne peux pas faire plus sinon on utiliserait tous inévitablement des streams compressés (gain de mémoire et amélioration de la vitesse).
On va s'arreter la ca il ne s'agit pas d'un topic (désolé Carbensila).
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
27 juin 2006 à 11:17
le memoustream est le contenant. Tu le considères comme un disque mais en 1000 fois plus rapide et ce qui est dans le memorystream comme un fichier. tu manipules les données comme un fichier sur disque: tu fais les manipulations avant d'envoyer les données et après les avoir retirées.
Pour générer une archive en mémoire il faut que tu ais accès à un tampon que tu charges dans le stream. (le plus facile c'est quand le composant possède une méthode saveto stream)
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
27 juin 2006 à 10:57
-> JLen100
Bon, il va falloir vous mettre d'accord... :)
Le memorystream est il le fichier ou le "tuyau" ?
Comme tu dis, les données sont inaccessibles quand elles sont compressées. Je n'ai pas besoin d'y accéder. Ce que je voudrais voir, c'est si on peut générer une archive dans la mémoire. Pour le moment, j'ai plus ou moins réussi à compresser le memorytream, mais j'ai l'impression que le composant que j'utilise est buggé (j'avais déjà eu le pb en manipulant des fichiers). L'avantage de compresser en mémoire c'est que c'est instantané...
A suivre
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
27 juin 2006 à 10:21
-->Simonpelloquin,
un memorystream est un fichier en mémoire on l'utilise comme un fichier et tu disposes d'à peut près des même fonctions (read, write, seek,...) plus quelques une comme loadfromfile, loadfromstream, savetofile,savetostream,position,....)
pour ton problème de compression de données il te faut les compressser avant et le décompresser après relecture comme tu le fairais sur disque ; mais avec les même limites que sur disque à savoir : la structure n'étant plus linéaire que tu ne pourras pas connaitre dans le flux la position exacte d'une donnée (compression oblige) cette méthode n'est donc valable que si tu transfert un bloc complet de données.

@+
jlen
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
27 juin 2006 à 10:05
>> Francky23012301
Si j'ai bien compris, un memorystream c'est le moyen de placer quelque chose dans la mémoire (fichier, chaine...). Mais alors, qu'est-ce qu'on obtient à l'arrivée ? Comment pointer vers les données stockées en mémoire ?
Par ailleurs, j'ai regardé sur les composants de compression Abbrevia (-> Caribensila : de chez Turbopower, librairie de composants opensource), il existe deux méthodes "InflateStream(Source, Dest : TStream)" et "DeflateStream(Source, Dest : TStream)" qui permettent de compresser et décompresser un stream (mais c'est buggé, j'ai un message qui me dit "lecture en dehors du flux" ou un truc de ce genre...). J'ai retrouvé ces même méthodes dans la librairie "zLib" (également opensource) pour Delphi (que je n'ai pas encore testé, mais ça va pas tarder...). Donc, mon cher Francky, pour résumer, j'ai bien compris et acquis tes explications, je pense qu'il s'agit d'un abus de langage (inflate et deflatestream doivent en fait dupliquer des données).
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
26 juin 2006 à 22:28
:) J'aime bien l'image employée par Francky23012301... Très didactique!

--> simonpelloquin
La démo montre comment sauvegarder un bitmap... Mais, bien sûr, sauf cas exceptionnels, on aura toujours intérêt à compresser ce bitmap en JPEG avant de le sauvegarder dans un fichier binaire...
D'ailleurs, un JPEG n'est rien d'autre qu'un fichier binaire comportant des tas de données relatives à la décompression en début de fichier.
Je ne connais pas 'abbrevia' mais je pense qu'il te faudra passer par ce genre de truc pour obtenir ce que tu veux...
@+
Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
26 juin 2006 à 21:33
Ce que je veux dire c'est que tu peux compresser tes données pas ton stream.
Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
26 juin 2006 à 21:32
Un stream est un flux continu de données.
Les blocks constitue un flux discontinu de données.
Autrement dit un block est une brouette pour déplacer un bac à sable d'un endroit A à un endroit B en faisant plusieurs fois le chemin. Un stream est une canalisation qui va de A vers B et qui va te permettre de déplacer de facon continu ton sable. Comment veux tu compresser un tuyau ???
sp40 Messages postés 1276 Date d'inscription mardi 28 octobre 2003 Statut Contributeur Dernière intervention 3 juillet 2015 15
26 juin 2006 à 16:42
Bonjour,
En reprenant cette source, j'ai "binarisé" un ensemble de fichiers paradox. C'est pas mal pour faire un seul fichier de sauvegarde à partir de plusieurs fichiers d'une base de donnée et c'est quasi instantané. En revanche, pour le transport des données, c'est pas top puisque les fichiers ne sont pas compressés... D'où ma question : Existe-t-il un moyen de compresser un stream ? (qui permettrait d'avoir un fichier de sauvegarde compressé sans utiliser de composants supplémentaires du type abbrevia)
Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
23 juin 2006 à 21:39
Une nouvelle idée de tuto CariBensila ?? Mdrrrr

Quand à Delphiprog, je suis pas sur qu'il s'attendait à faire des rencontres du troisième type en allant à la rencontre de CS. Mdrrrrr. En tout cas tu peux dire merci à la DDE ;).

A+
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
23 juin 2006 à 11:04
Très instructif!
Merci pour vos lumières.
En tout cas, je retiendrai 2 choses:

1) Pour optimiser l'espace mémoire, il vaut mieux utiliser des String plutôt que des ShortString, contrairement à ce qu'on pourrait croire. Et utiliser Integer au lieu de Byte pour optimiser les temps de traitement (si j'ai bien capté).

2) Que le Bois de Boulogne est une bonne solution pour s'initier au type Variant. ;)
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
23 juin 2006 à 10:44
oui on dérive un peu
d'accord avec toi pour l'alignemnt sur 4 octets mais il me semble que delphi le fait dans l'optimisation.
il faut également savoir que dans certains cas il vaut mieux déclarer un integer plutot qu'un byte (j'ai eu le cas récemment d'un plantage sur une erreur de convertion dans un findcomponent avec inttostr(byte) que je n'avais pas avec inttostr(integer)) de même on peut avoir de mauvaises surprises avec des fonctions windows renvoyant des LONGBOOL si on affecte directement la fonction à un boolean.
C'est vrai que ce sont des finesses qui dépassent le simple code mais si l'on a pas un minimum de connaissance de l'architecture et de la structure des variables on peut galérer longtemps avant de comprendre ce qu'il se passe.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
23 juin 2006 à 10:09
OK cette fois je vois de quoi tu parles.
Cependant, l'adressage direct par 4 octets ne doit pas être systématique, il convient de vérifier si on est sur une adresse multiple de 4 sinon on prend des cycles de pénalité (Win rattrape erreur processeur mais cela coute) alors qu'un adressage sur 8 bits ne souffrira jamais de cela. Si donc l'alignement n'est pas multiple de 4 il faut transférer par octet afin de se rendre sur le bon alignement avant de transférer par 4.
Il me semble que cette discussion entre dans des finesses qui dépassent ce qu'on peut controler par un simple code delphi.
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
23 juin 2006 à 09:45
salut BRUNEWS,
il ne s'agit d(instruction assembleur mais d(opéation interne au processeur.
ben que ce soit transparent au niveau du code c'est différent au niveau du processeur. Il travaille avec un bus 32bits (même 64 sur les dernières générations) quand tu demandes un transfert de 8 bits il doit quand même soit transférer 32 bit en récupérant les autre octets de la mémoire cache soit changer le mode d'adressage (cela dépend de l'architecture du pross. et du constructeur) mais dans tout les cas cela demande au moins un cycle machine (pas une instruction)
pour faire une comparaison grossière : extrait ou modifie un bit au niveau d'un octet et range le. Tu auras une idée de ce que fait le processeur en interne de façon totalement transparente mais qu'il doit bel et bien faire pour assurer l'intégrité des données.
d'autre part quand tu travailles sur une suite d'octets contigus tu as tout intérêt à charger les 4 octets dans un registe à faire les opérations sur les registres 8 bits puis à transférer les 4 octets en 1 fois plutot que de le faire octet par octet
Je ne t'apprendrai rien en te disant que suivant les modes d'adressage utilisés ou que tu utilises la mémoire ou les registres les différences de performances peuvent aller de 1 à 10 voir de 1 à 50. Si c'est une instruction que tu n'utilises qu'une fois cela n'a pas d'importance par contre si cette instruction est répétée plusieurs milliers de fois (c'est généralement le cas quand tu crées des routines en assembleur) c'est très sensible.

@+
jlen
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
23 juin 2006 à 02:00
Pas tout compris à ton transfert de 4 octets et de l'opération supplémentaire pour accéder à 1 octet:
mov al, dl // REG => REG = direct
mov al, [edx] // MEM => REG, direct
mov [edx], al // REG => MEM, direct
l'affectation sur 8 bits se fait directement et sans cycles de pénalité, qu'ai-je zappé dans ton explication ?
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
23 juin 2006 à 00:01
-->Caribensila comme il existe plusieurs façons d'optimiser tout dépend ce que l'on recherche:
si l'on recherche un gain d'espace il vaut mieux n'enregistrer de les données utiles
si l'on recherche un temps d'accès minimum il vaut garder des tailles d'enregistrement fixes.
si l'on veut aller plus loin il y a d'autres données qui occupe plus d'espace que nécessaire ainsi si l'on prend une valeur numérique A:integer; et A:=1; A occupera 4 octets alors que sa taille utile est de 1 octet (plus exactement 1 bit) mais pour des questions de gestion matérielle de la mémoire sur un système 32bits il est préférable de travailler sur 4octets (et sur 8 octets pour les systèmes 64bits) puisque de toute façon le processeur transfèrera les 4 octets en une seule opération et qu'accéder à 1 octet paticulier du bloc demande au moins une opération supplémentaire
Pour les tableaux dynamiques ils ont besoins de 8 octets en plus des données: un pointeur de 4 octets dans le gestionnaire de tas et 4 octets pour la taille des données et en termes de performance cela peut devenir catastrophique. Une erreur de débutant quand on traite des chaînes de caractère par exemple quand on fait
str:string;
for i:=0 to XXX do str:=str+'A';

à chaque fois que l'on ajoute 'A' à str en fait le programme crée une variable temporaire il faut qu'il appelle le gestionnaire de tas pour allouer la mémoire correspondant à str+'A' ensuite il copie str dans la variable temporaire puis ajoute 'A' il rapelle le gestionnaire de tas pour désalouer la mémoire correspondant à la variable initiale et enfin il affecte la variable temporaire à str ce qui doit correspondre à un bon millier d'opération contre 4 à 5 quand on fait str[i]:='A' et en affectant str[0]:=i à la sortie de la boucle. de même pour travailler sur des chaines longues on a queleques fois intérêt à la copier dans un tableau.
et les recopier dans un string après traitement.
-->delphiprog au bois de Boulogne il y a aussi le type Tsexe=Trans; particulièrement trompeur!!

@+
jlen
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
22 juin 2006 à 23:06
Mauricio : tu ne peux pas écrire
FileStream.WriteBuffer(MaString[2], Taille)
car :
- les chaines standards sont des chaines à zéro terminal et que donc tu lis au dela du caractère nul de fin de chaine !
Pointeur sur chaine -->MAURICIO0 <-caractère nul indiquant la fin de la chaine
Si tu veux démarrer au deuxième caractère, tu dois alors réduire la valeur de taille de 1.

Avec les chaines courtes, le problème est différent comme l'a fait remarquer Caribensila puisque la longueur est stockée à l'octet zéro de la chaine. Les chaines courtes ont encore leur utilité pour transmettre facilement à une DLL si on ne veut pas manipuler les PChar.

Avec les tableaux de caractères, il faudra penser aussi à initialiser le tableau avant de l'écrire dans un stream :
carArray: array[0..255] of char;
FillChar(carArray, SizeOf(carArray), 0);

FileStream.WriteBuffer(carArray, SizeOf(carArray));

Pour Jlen100, je confirme la réponse de Caribensila : sizeOf(MaString) renvoie bien la longueur du tableau.

@Caribensila : je confirme pour le bois de Boulogne. J'ai pu le vérifier dernièrement (Jlen100 m'aura compris :o) ).
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
22 juin 2006 à 19:04
Exact jlen100:
sizeOf(MaString) renvoie bien la longueur du tableau et non celle de la chaîne.
Ainsi, quand je fais:
TPersonne = Record
Nom : String[20];
MonRecord.Nom := 'Caribensila';
FileStrm.WriteBuffer(MonRecord.Nom,SizeOf(MonRecord.Nom));

ça écrit bien les 21 octets de String[20] sur le disque, et non pas les 11 octets de la String 'Caribensila'.
C'est un petit manque d'optimisation que vos remarques m'ont fait découvrir. :s
Par contre pour les chaînes longues c'est optimisé car je prends length(MaSting) comme taille en octets...
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
22 juin 2006 à 18:39
declarer : MaString : String[200];
revient à déclarer un tableau statique :
MaString : Array[0..200]of char;(non compatible avec le type string)
dans ce cas le compilateur pointe sur MaString[0] et en principe (je n'ai pas vérifié) sizeOf(MaString) renvoie la longueur du tableau et non celle de la chaine.
note aussi que tu peux transtyper ta chaine en PChar.
Dans le cas d'un tableau dynamique on ne transfert que les données la taille du tableau étant ajustée à celles-ci
D'ailleurs quand on enregistre un fichier typé l'espace occupé est celui des N enregistrements et non celui des données réelles ce qui permet de se déplacer dans le fichier par seek(position) ou position= Nième enregistrement*taille enregistrement ce qui n'est pas possible avec des tableaux dynamiques ou il faut soit lire les données séquentiellement soit rajouter une structure descriptive au fichier(cas des bases de données)ce qui peut être infiniment plus complexe

@+
jlen
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
22 juin 2006 à 18:09
Pour éclairer ma lanterne j' ai fait le test suivant:
J' ai déclaré comme suit:
MaString : String[200];

Il faudra faire comme ça sinon ça marche pas:
FileStrm.WriteBuffer(MaString,Taille);
FileStrm.ReadBuffer(MaString,Taille);

étant donné que l' on utilise plus une ShortString je pense ...

Par contre (et là ça devient interessant), j' ai remarqué que si on déclare :
MaString : String;
Ça ne marche que comme ça (méthode initiale):
FileStrm.WriteBuffer(MaString[1],Taille);
FileStrm.ReadBuffer(MaString[1],Taille);

conclusion:
MaString := String[200] n' est pas une ShortString?!
MaString : String fonctionne comme si c' était une ShortString ...

Hors, d' après ce que l' on peut lire plus haut, ça na plus de sens ...

D' ailleurs, on a bien dans la source:
TPersonne = Record
Nom : String[20];
FileStrm.WriteBuffer(MonRecord.Nom,SizeOf(MonRecord.Nom));

Je suis perdu cette fois et vous??? :)
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
22 juin 2006 à 17:49
Merci pour toutes ces précisions les gars!!!
Ok, j' ai pigé ça: le type ShortString qui a un max. de 255 caractères rappelons le, possède l' info de sa taille dans son 1er octet (byte en Anglais). Cette valeur peut être connue gràce à Ord(S[0]) ou Byte(S[0]) ...

Donc lorsque l' on a :
FileStrm.WriteBuffer(MaString[1],Taille);
Ça veut dire que l' on saute donc l' info de la taille de MaString pour ne garder que la chaine de caracteres proprement dite ?!!!!

Ok, cette fois je crois que c' est ça... !!!
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
22 juin 2006 à 17:40
Merci pour ces précisions, jlen100.

D'ailleurs, je signale que le type ShortString possède encore cette particularité de l'indice 0.
Par exemple une chaîne S : String[20];
Pour en connaître la taille, on peut faire Ord(S[0]) ou Byte(S[0]) au lieu de length(S).
Mais ça ne marche plus pour le type String.
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
22 juin 2006 à 16:57
--->MAURICIO cela tient à la structure de TString qui hérite de celle du pascal : les données commencent à l'indice 1 et non à l'indice 0 (en pascal l'indice 0 était réservé à la longueur)
Quand tu passes une chaine à un paramètre non typé c'est comme si tu passais un tableau dynamique il faut lui indiquer l'indice

@+jlen
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
22 juin 2006 à 10:16
Merci DelphiProg pour cette précision même si je comprends toujours pas pourquoi avec maString[1] ça marche ...

Petite remarque quand même, je pense que TSexe devrait être déclaré comme ça:
TSexe = (Homme,Femme,LesDeux);
A+
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
22 juin 2006 à 03:36
à ton service, Delphiprog.
L'adresse:

Paris/Bois de Boulogne

Y'a plein de variables non typées...
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
21 juin 2006 à 23:51
Ce code m'aura révélé au moins une chose, il existe un troisième sexe (lol) :
TSexe = (Homme,Femme,Sexe);
Alors, Caribensila, si tu connais des exemples, sois gentil, donne les nous...

Pour répondre à la question de Mauricio "mais pourquoi diable ça ne marche pas (j' ai essayé) tout simplement comme ça:
FileStrm.WriteBuffer(MaString,Taille);"

Si on regarde la déclaration de la méthode WriteBuffer :
procedure WriteBuffer(const Buffer;Count:Longint);

Buffer est une adresse mémoire d'un contenu non typé. Ceci explique qu'il faille passer et une adresse et une longueur (deuxième argument).

Personnellement, je préfère utiliser les méthodes Write et Read qui renvoient respectivement le nombre d'octets écrits ou lus.

Bon travail.
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
21 juin 2006 à 18:12
Au sujet de ta 1ère remarque:
T'as raison, ça doit être frustrant! s)
En fait, je n'avais prévu que d'afficher le contenu des variables à sauvegarder (puisque je n'ai pas prévu de pouvoir changer le contenu des autres variables dans ce source). Je mettrai la propriété ReadOnly du TEdit à true pour concerver une certaine cohérence dans cette démo... :)

Ta 2ème remarque (d'après ce que j'en ai compris):
Je crois que pour Delphi, un String est un flux. Il doit donc être traité comme tel. En transmettant l'adresse du premier caractère, on initialise la position de l'index de ce flux au début...
Je pense que
FileStrm.WriteBuffer(MaString,Taille);
ne sauvegarderait qu'un pointeur (un Integer).
Or, ce serait un non-sens que de sauvegarder un pointeur qui change selon l'humeur du système...
Mais bon... J'avoue que j'atteins mes limites, là.
Si toi, ou qqun d'autre, peuvent apporter leurs lumières, je serais toute ouïe.

Pour ta parenthèse, je dirai que t'as tout de suite compris l'intérêt des fichiers binaires. Ca peut être de la vraie programmation. On n'est même pas obligé de créer des fichier linéaires, comme ma démo. On peut aussi prévoir des accès conditionnels, etc... Question d'imagination!

En tout cas, j'apprécie ces remarques qui m'aident à progresser.
Merci MAURICIO.
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
21 juin 2006 à 15:55
Juste une parenthèse si tu me le permets Caribensila,
imaginons un fichier binaire qui comporterait plusieurs images, du texte etc ... en nombre indéfini comme dans un fichier de type Word par exemple.

Pour ceux que ça interesse il suffit d' organiser le flux comme ça:
-> Signature+taille contenu (entier) +type contenu (entier)+ flux du contenu

ça donnerai un fichier comme ça :
-> Signature+taille contenu (entier) +type contenu (entier)+ flux du contenu + taille contenu (entier) +type contenu (entier)+ flux du contenu + taille contenu (entier) +type contenu (entier)+ flux du contenu + taille contenu (entier) +type contenu (entier)+ flux du contenu etc ...

"type contenu" définit si on a affaire à une image, du texte ou autre chose ...
A+
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
21 juin 2006 à 15:41
Re-bonjour!
elle est trop interessante cette source pour na pas se jeter dessus!!!
Donc, voilà ce que j'en pense: béton!!!

Le procédé de création du fichier est simple:
->Garder un entier avec la taille necessaire
->Garder ce que l' on a à garder (string, image etc ...)
Simple...oui, c' est vite dit quand même!!!

Remarque:
--------------
Dans le bouton de sauvegarde, il faudrait ajouter cette ligne:
MaString := Edt_String.Text;
C' est embêtant de changer le texte, cliquer sur sauvegarder, puis sur charger et de voir que notre nouveaux message n' appararaisse pas...



Arg, j' ai pas trop compris la 2ème ligne ici, l' utilisation de MaString[1] :
FileStrm.WriteBuffer(Taille,SizeOf(Taille));//On écrit d'abord la taille de la chaîne qui va suivre(un Integer, donc) ...
FileStrm.WriteBuffer(MaString[1],Taille);//...puis la chaîne en transmettant un pointeur sur son 1er caractère, et sa taille.
Si je mets MaString[2] il commence à garder depuis le second caractere, ça j' ai compris ...
mais pourquoi diable ça ne marche pas (j' ai essayé) tout simplement comme ça:
FileStrm.WriteBuffer(MaString,Taille);

Merci encore une fois Caribensila, t' es le meilleur !!! A+
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
21 juin 2006 à 13:28
Salut MAURICIO,
Voici un compliment qui me va droit au CPU ;) Et ça fait du bien car c'est notre seule récompense, n'est-ce pas?
Surtout connaissant la pertinence de tes interventions ici (bien que devenant trop rare, je trouve).
J'attendrai donc tes commentaires constructifs, comme d'hab...
... Et admiration pour ta mémoire! La démo sur le clipboard ne date pas d'hier! lol
@+
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
21 juin 2006 à 11:28
Bonjour Caribensila,
encore une source indispensable de voir!!!
Si je me souviens bien, celle du clipboard était de toi aussi.
Malheureusement, je ne verrai cette source qu' en fin de semaine mais je voulais laisser un petit message de remerciement pour tes sources de qualité exceptionnelles...
Bravo et merci encore une fois, A+
Rejoignez-nous