mkolivier
Messages postés11Date d'inscriptionmardi 8 juillet 2003StatutMembreDernière intervention18 octobre 2013
-
13 mars 2006 à 16:54
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 2022
-
17 mars 2006 à 13:53
Bonjour,
Je souhaiterai faire un fichier avec plusieurs types. Par exemple :
type TEnteteFichier = record
Version: integer;
ExtensionFichier: string[10];
f: file;
end;
type TLignefichier = record
Nom: string[50];
Prenom: string[100];
Age: integer;
end;
procdure Enregistrer();
var
Head: TEnteteFichier;
Ligne: TLignefichier;
begin
Head.Version := 3;
Head.ExtensionFichier := '.abc';
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 14 mars 2006 à 08:14
Salut,
En supposant que tu voulais écrire :
type TEnteteFichier = record
Version: integer;
ExtensionFichier: string[10];
end;
type TLignefichier = record Nom: string[50];
Prenom: string[100];
Age: integer;
end;
var f : File;
Je dirais qu'il y a plusieurs réponses :
Si le fichier est constitué alternativement de TEnteteFichier et de TLigneFichier, il faut créer un type
type TEnregitrement = record
Entete : TEntetFichier;
Ligne : TLigneFichier;
end;
et
var Data : TEnregistrement;
f : file of TEnregistrement;
procedure Enregistrer;
var Head: TEnteteFichier;
Ligne: TLignefichier;
end ;
AssignFile(f, 'c:\test.dat');
Rewrite(f);
Write(f, Data);
Closefile(f);
end;
Si le fichier est constitué d'un seul TEnteteFichier suivi d'un nombre inconnu de TLigneFichier, tu peux utiliser (comme tu le fais) un fichier non typé, mais alors, il faut savoir lui causer ! Avec BlockWrite et BlockRead
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 13 mars 2006 à 19:58
Salut,
Bon éclaire moi déjà sur ces deux points en rouge, je pense que ton problème vient de là
type TEnteteFichier = record Version: integer;
ExtensionFichier: string[10]; // 4 aurait suffit et 100 pour un prénom ça beaucoup aussi mais bon c'est ton choix
f: file; // c'est pour quoi ça ?
end;
AssignFile(f, 'c:\test.dat'); // et ici de quel type est F ?
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 14 mars 2006 à 04:08
rhaaa ... je viens de me rendre compte qu'encore une fois j'ai fait tout le boulot :
et pourtant je dis bien au debut :
"un conseil, quand tu ecris un type enregistrement (record) n'oublis pas
de faire la fonction qui vas bien avec, ici pour tes deux exemples :"
et paf je pond tout le programme ... lol
faut que j'arrete.
<hr size="2" width="100%">La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
mkolivier
Messages postés11Date d'inscriptionmardi 8 juillet 2003StatutMembreDernière intervention18 octobre 2013 16 mars 2006 à 22:12
Merci pour vos réponses, j'ai juste une question : pourquoi les fichiers générés sont si lourd ? car si je prends l'exemple de Kenavo, le fichier test.dat fait 80 ko c'est énorme pour ce qu'il y a dedans !!!
Vous n’avez pas trouvé la réponse que vous recherchez ?
mkolivier
Messages postés11Date d'inscriptionmardi 8 juillet 2003StatutMembreDernière intervention18 octobre 2013 16 mars 2006 à 23:03
Désolé je reviens ici en fait c'est ok, c'est marrant (je suis encore débutant), je n'avais pas vu qu'en mettant Rewrite(f, 1) ou Rewrite (f), le résultat est différent, le fichier est beaucoup moins lours en mettant le 1 en paramètre. Par contre le "1" cela signifie quoi ?
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 17 mars 2006 à 00:19
Salut,
si tu veux gagner de la place c'est ici que ça se passe:
type TEnteteFichier = record
Version: integer; // 4 Octets ExtensionFichier: string[10]; // 10 + 1 = 11 Octets end;
type TLignefichier = record
Nom: string[50]; // 50 + 1 = 51 Octets Prenom: string[100]; // 101 Octets Age: integer; // 4 Octets;
end
Ce qui nous fait 15 Octets pour l'entête et 156 par Ligne ce qui fait 171 Octets pour un fichier avec une entête et une ligne.
type TEnteteFichier = record
Version: integer; // Si Version n'est pas plus grand que 255 tu peux utiliser Byte il ne prend que 1 Octet
ExtensionFichier: string[4]; // 4 + 1 = 5 Octets end;
type TLignefichier = record
Nom: string[20]; // 20 + 1 = 21 Octets avec 15 c'est déjà un chouette nom Prenom: string[15]; // 15 + 1 = 16 Octets avec 15 c'est déjà un chouette prénom Age: Byte;
// 1 Octets; on a rarement vu quelqu'un de plus de 255 ans
end
Ce qui nous fait 6 où 9 Octets pour l'entête en fonction de Byte où Integer et 38 Octets par ligne ce qui fait un fichier de 44 à 47 Octets
Alors bien évidement sur 1 enregistrement c'est déjà remarquable tu peux t'imaginer sur une centaine
Ensuite pour l'histoire de rewrite(f, 1) où rewrite(f) fait un F1 pour comprendre que ce n'est pas ceci qui va influencer sur la taille du fichier
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 17 mars 2006 à 08:12
Et encore, Cirec tu ne tiens pas compte de l'alignement des données ! Si je je me trompe pas, les données sont alignées sur 8 octets (par défaut par le compilateur de D7) ou 4 octets
(par défaut par le compilateur de D4).
Pour prendre le minimum de place (et pour que le fichier d'enregistrements soit lisible, quelque soit l'alignement) il faut utiliser des Packed Record
au lieu de simples record dans les définitions de type. Sinon, un octet (byte) occupe 8 octets, soit autant qu'un int64 ou qu'un double !
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 17 mars 2006 à 10:24
Alors la, Kenavo, j'avoue que ça dépasse un peut mes connaissances, tout ce que je sais c'est ce que j'ai testé et quand je donne une taille de 171 Octets j'obtiens 172 Octets avec le compilateur D4 et si j'examine le fichier en hexa je retrouve ce que j'avançais plus haut : 1 Octet pour un Byte, 4 Octets pour un Integer, 11 Octets pour un String[10] : 10 Octets sont présents pour la taille maximale admise pour ce String et 1 Octet est ajouté devant pour la taille réel à lire. Comme je ne trouve pas de grande différence entre mon calcule et la réalité (1 Octet que j'ai mis sur le compte de l'EOF ?) je me dis que je ne dois pas être loin de la réalité
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 17 mars 2006 à 13:17
Cirec, tout en principe, Dans Delphi 4, dépend d'une case à cocher dans les options du compilateur (champs de données alignés), ou de la directive {$A+}{$A-}
Dans Delphi 7, au lieu d'une case à cocher, on dipose d'une combo, qui permet d'aligner les champs à 1 octet (non aligné),2, 4 ou 8
Il y a en plus, des subtilités : l'aide dit que :
Type Alignement
Types scalaires Taille du type (1, 2, 4 ou 8)
Types réels 2 pour Real48, 4 pour Single, 8 pour Double et Extended
Types chaînes courtes 1
Types tableau Identique au type des éléments du tableau
Types enregistrements Le plus grand alignement des champs de l'enregistrement Types ensembles Taille du type si 1, 2 ou 4, sinon 1
Tous les autres types Déterminé par la directive $A.
Donc, pour les type enregistrement, c'est plus complexe que je ne le pensais ! Il suffit qu'il y ait des types scalaires différents dans le même record
Je m'étais penché sur ce problème lorsque j'avais voulu relire avec Delphi (2 ou 4) un fichier d'enregistrements créé avec turbo Pascal ! Ça ne marchait pas ! Enfer et damnation ! Jusqu'à ce que je découvre cette histoire d'alignement !
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 17 mars 2006 à 13:53
Alors la, je ne savais même pas qu'on pouvait agir sur l'alignement des champs je les ai toujours utilisé tel quel.
Bon il faut absolument que je regarde ça de plus près. Quand on apprend tout seul on a forcement des lacunes.
Merci pour la précieuse information.