|
Publicité | ||||||||||||||||||||||
|
|
#1 (permalink) |
|
Membre éclairé
![]() Date d'inscription: septembre 2005
Localisation: HERBLAY 95
Âge: 64
Messages: 336
|
Bonsoir à toutes et à tous,
Avec la procédure Append, il est possible d'ajouter du texte à la fin d'un fichier ... Texte. Cette procédure ne fonctionne pas pour les autres types de fichiers. Or j'ai un fichier composé d'enregistrements (record) et je voudrais y ajouter toutes les X minutes un nouvel enregistrement sans avoir à ré-enregistrer tout le fichier et que cela fonctionne sous Windows et sous Linux. Je n'ai pas trouvé de méthodes pour cela (peut-être mal cherché). En existe-t-il ? J'ai essayé un transtypage : Code :
type TVals = record A, B: Integer; end; var Vals: TVals F: Text; ... AssignFile(F, MonFichier); Append(F); Write (F, string(Vals.A)+string(Vals.B)); {Plantage} ... Merci de votre aide. Pierre Dernière modification par ChPr ; 06/02/2010 à 23h40. |
|
|
|
|
|
#2 (permalink) |
|
Membre chevronné
![]() Date d'inscription: septembre 2009
Localisation: Tardis
Âge: 31
Messages: 682
|
TFileStream!
Code :
// creation with TFileStream.Create(fileName, fmOpenReadWrite) do try // on vas a la fin Position := Size; // on ecrit Write(Value, SizeOf(TValue)); finally // on libère Free; end;
__________________
[ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ] Ma messagerie n'est pas la succursale du forum... merci! Dernière modification par Dr.Who ; 08/02/2010 à 01h13. |
|
|
|
|
|
#3 (permalink) |
|
Nouveau membre du Club
![]() Date d'inscription: janvier 2010
Localisation: Gironde
Âge: 37
Messages: 63
|
Methode 1 : Lire tous les enregistrement du fichiers puis ajouter.
Code :
program FileTest; uses SysUtils; type TVals=record A, B : Integer; end; var Vals : TVals; F : file of TVals; I : Integer = 0; begin Assign(F,'vals.bin'); FileMode:=fmOpenReadWrite; Reset(F); while not Eof(F) do begin Read(F, Vals); WriteLn(I, ': A=', Vals.A, ' B=', Vals.B); I := I + 1; end; Write('A='); ReadLn(Vals.A); Write('B='); ReadLn(Vals.B); Write(F,Vals); end. Code :
program FileAppend; uses SysUtils; type TVals=record A, B : Integer; end; var Vals : TVals; F : LongInt; begin F := FileOpen('vals.bin', fmOpenReadWrite); FileSeek(F, 0, fsFromEnd); Write('A='); ReadLn(Vals.A); Write('B='); ReadLn(Vals.B); FileWrite(F,Vals, SizeOf(TVals)); FileClose(F); end. |
|
|
|
|
|
#4 (permalink) |
|
Membre éclairé
![]() Date d'inscription: septembre 2005
Localisation: HERBLAY 95
Âge: 64
Messages: 336
|
Merci pour les solutions que vous m'apportez.
Pour le moment, j'ai choisi d'utiliser "TFileStream". Par contre, il ne faut pas faire : Code :
Position:= Size-1;
Code :
Position:= Size; Pierre |
|
|
|
|
|
#5 (permalink) |
|
Membre chevronné
![]() Date d'inscription: septembre 2009
Localisation: Tardis
Âge: 31
Messages: 682
|
exact
__________________
[ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ] Ma messagerie n'est pas la succursale du forum... merci! |
|
|
|
|
|
#6 (permalink) |
|
Membre chevronné
![]() Date d'inscription: septembre 2009
Localisation: Tardis
Âge: 31
Messages: 682
|
et cerise sur le gateau avec TFileStream :
Code :
type TVal = packed record A, B: integer; end; PVals = ^TVals; TVals = array of TVal; procedure ValsSave(FileName: string; lpVals: PVals); var vCount : integer; vSize : integer; begin with TFileStream.Create(FileName, fmCreate) do try vCount := Length(lpVals^); vSize := vCount * SizeOf(TVal); Write(vCount, 4); Write(vSize, 4); Write(lpVals^, vSize); finally Free; end; end; procedure ValsLoad(FileName: string; lpVals: PVals); var vCount, vSize: integer; begin with TFileStream.Create(FileName, fmOpenRead) do try read(vCount, 4); read(vSize, 4); assert(vSize <> (vCount*SizeOf(TVal)), 'Size not match'); SetLength(lpVals^, vCount); read(lpVals^, vSize); finally Free; end; end;
__________________
[ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ] Ma messagerie n'est pas la succursale du forum... merci! |
|
|
|
|
|
#7 (permalink) |
|
Nouveau membre du Club
![]() Date d'inscription: janvier 2010
Localisation: Gironde
Âge: 37
Messages: 63
|
Après consultation d'un bouquin la bonne méthode pour ajouter des données à la fin d'un 'file of Type' c'est :
Code :
Assign(F,'vals.bin'); Reset(F); // Ouvre en lecture/écriture Seek(F, FileSize(F)); // Aller à la fin Write(F,Vals); // Ecrire Close(F); |
|
|
|
|
|
#8 (permalink) |
|
Membre éclairé
![]() Date d'inscription: septembre 2005
Localisation: HERBLAY 95
Âge: 64
Messages: 336
|
Merci pour ces compléments d'info.
Cependant, j'ai un problème avec la méthode que préconise "batyann811". Le fichier "original" que je récupère auquel je dois rajouter des valeurs est constitué de N enregistrements de X octets suivi d'un enregistrement de taille différente (Y octets). Avec TFileStream, cela ne me pose pas de problème car "Size" me retourne le nombre d'octets du fichier. Je vais donc à la fin moins Y octets, j'écris mes enregistrements de X octets et je peux y rajouter au final l'enregistrement de Y octets (mais je ne le fais pas car cela ne me sert à rien). Avec Assign(F, 'MonFichier'), "FileSize" me retourne un nombre d'enregistrements de la taille du type de F (soit X octets dans mon cas). Je ne sais pas comment il prend en compte le dernier enregistrement de Y octets. Comme dit plus haut, je ne remets pas l'enregistrement de Y octets à la fin de mes fichiers. Donc, je ne sais pas distinguer à l'ouverture un fichier original d'un fichier que j'ai complété. En tout état de cause, dans mon cas précis, la mise en œuvre de cette dernière méthode est plus compliquée que celle utilisant TFileStream. Mais je garde les deux sous le coude car elles sont intéressantes. Cordialement. Pierre |
|
|
|
|
|
#9 (permalink) |
|
Nouveau membre du Club
![]() Date d'inscription: janvier 2010
Localisation: Gironde
Âge: 37
Messages: 63
|
Les fichiers définis pas 'file of TRecord' ne peuvent contenir que des TRecord.
Les TFileStream sont en réalité des flux d'octets on peut donc y lire et écrire des 'objets' de tailles différentes. En contrepartie à chaque lecture ou écriture il faut spécifier la taille de ce que l'on veut lire ou écrire. On peut obtenir le même comportement en utilisant un 'file of byte' et les procédure BlocRead et BlockWrite. |
|
|
|
|
|
#10 (permalink) |
|
Membre chevronné
![]() Date d'inscription: septembre 2009
Localisation: Tardis
Âge: 31
Messages: 682
|
le problème des file of type c'est justement qu'on ne peut mettre QUE des données du type definis ou de taille condordante.
exemple : avec un File of TPoint, on peut lire un TSize, avec un File of TRect on peu lire un TPoint. mais pas l'inverse, lire un TRect dans un file of TPoint risque de poser quelques problèmes en fin de fichier si le nombre de point est impair. le Stream est plus polyvalent, on peut lire/ecrire ce que l'on veux dedans, stream est à peu prés équivalent à un type File (fichier non typé) sans les problèmes qu'il peut engendré. sinon, quand je definit un format brut de donnée, je m'arrange toujours pour stocker quelques infos en début de fichier. signature du fichier, nombre de données, taille de ces derniere, header, footer, table de verification, compréssion, offset etc. ici, tu peux te contenter d'une structure, comme dans l'exemple : [count LongWord][theorical size LongWord][date undefined] ce qui donne : Code :
Read/Write( count, 4 ); Read/Write( Size, 4 ); test Size= Stream.Size -> continue/stop Read/Write( datas, Size ); ou boucle N 0 -> Count-1 Read/Write( data, SizeOf(Data) );
__________________
[ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ] Ma messagerie n'est pas la succursale du forum... merci! |
|
|
|
|
|
![]() |
||
[Lazarus] Ajouter un enregistrement à un fichier
|
||
| Outils de la discussion | |
|
|