Précédent   Forum des professionnels en informatique > Autres langages > Pascal > Lazarus
Lazarus Forum d'entraide sur Lazarus, le RAD de FreePascal, à la poursuite de Delphi
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
Vieux 06/02/2010, 23h28   #1 (permalink)
Membre éclairé
 
Avatar de ChPr
 
Date d'inscription: septembre 2005
Localisation: HERBLAY 95
Âge: 64
Messages: 336
Par défaut Ajouter un enregistrement à un fichier

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}
...
ça compile, mais ça plante à l'exécution. Il faut peut-être que je passe par un buffer ?

Merci de votre aide.

Pierre

Dernière modification par ChPr ; 06/02/2010 à 23h40.
ChPr est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 07/02/2010, 00h03   #2 (permalink)
Membre chevronné
 
Avatar de Dr.Who
 
Date d'inscription: septembre 2009
Localisation: Tardis
Âge: 31
Messages: 682
Par défaut

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.
Dr.Who est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 07/02/2010, 10h40   #3 (permalink)
Nouveau membre du Club
 
Date d'inscription: janvier 2010
Localisation: Gironde
Âge: 37
Messages: 63
Par défaut

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.
Methode 2 : Fonctions 'File*'
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.
batyann811 est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 07/02/2010, 19h18   #4 (permalink)
Membre éclairé
 
Avatar de ChPr
 
Date d'inscription: septembre 2005
Localisation: HERBLAY 95
Âge: 64
Messages: 336
Par défaut

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;
mais :
Code :
Position:= Size;
Cordialement.

Pierre
ChPr est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 08/02/2010, 01h13   #5 (permalink)
Membre chevronné
 
Avatar de Dr.Who
 
Date d'inscription: septembre 2009
Localisation: Tardis
Âge: 31
Messages: 682
Par défaut

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!
Dr.Who est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 08/02/2010, 01h27   #6 (permalink)
Membre chevronné
 
Avatar de Dr.Who
 
Date d'inscription: septembre 2009
Localisation: Tardis
Âge: 31
Messages: 682
Par défaut

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!
Dr.Who est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 08/02/2010, 09h53   #7 (permalink)
Nouveau membre du Club
 
Date d'inscription: janvier 2010
Localisation: Gironde
Âge: 37
Messages: 63
Par défaut

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);
batyann811 est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 08/02/2010, 15h31   #8 (permalink)
Membre éclairé
 
Avatar de ChPr
 
Date d'inscription: septembre 2005
Localisation: HERBLAY 95
Âge: 64
Messages: 336
Par défaut

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
ChPr est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 08/02/2010, 16h01   #9 (permalink)
Nouveau membre du Club
 
Date d'inscription: janvier 2010
Localisation: Gironde
Âge: 37
Messages: 63
Par défaut

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.
batyann811 est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 08/02/2010, 16h01   #10 (permalink)
Membre chevronné
 
Avatar de Dr.Who
 
Date d'inscription: septembre 2009
Localisation: Tardis
Âge: 31
Messages: 682
Par défaut

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) );
 
c'est quand même beaucoup plus simple
__________________
[ 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!
Dr.Who est déconnecté   Envoyer un message privé Réponse avec citation
NEWS PASCALF.A.Q PASCALTUTORIELSEXERCICESSOURCESCOMPILATEURSOUTILSLIVRES

Réponse Proposer ce sujet en actualité

Précédent   Forum des professionnels en informatique > Autres langages > Pascal > Lazarus



Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are non
Pingbacks are non
Refbacks are non



Fuseau horaire GMT +1. Il est actuellement 08h22.


Vos questions techniques : forum d'entraide Pascal - Publiez vos articles, tutoriels et cours
et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones
Nous contacter - Hébergement - Participez - Copyright © 2000-2010 www.developpez.com - Legal informations.