IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Lazarus Pascal Discussion :

Ajouter un enregistrement à un fichier


Sujet :

Lazarus Pascal

  1. #1
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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

  2. #2
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    TFileStream!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // 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!

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 235
    Points : 506
    Points
    506
    Par défaut
    Methode 1 : Lire tous les enregistrement du fichiers puis ajouter.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    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. #4
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    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 : mais : Cordialement.

    Pierre

  5. #5
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    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!

  6. #6
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    et cerise sur le gateau avec TFileStream :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    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. #7
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 235
    Points : 506
    Points
    506
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      Assign(F,'vals.bin');
      Reset(F); // Ouvre en lecture/écriture
     
      Seek(F, FileSize(F)); // Aller à la fin
     
      Write(F,Vals);  // Ecrire
     
      Close(F);

  8. #8
    Membre éprouvé
    Avatar de ChPr
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    2 022
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Val d'Oise (Île de France)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 2 022
    Points : 1 049
    Points
    1 049
    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

  9. #9
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    235
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 235
    Points : 506
    Points
    506
    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.

  10. #10
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    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!

Discussions similaires

  1. [WB19] Ajout d'un enregistrement à un fichier de données
    Par Tito47 dans le forum WebDev
    Réponses: 6
    Dernier message: 16/04/2014, 17h25
  2. [AC-2010] Ajout d'enregistrement lors d une exportation ver un fichier texte
    Par baloo42400 dans le forum Access
    Réponses: 4
    Dernier message: 10/04/2014, 15h51
  3. Ajout d'enregistrements dans un fichier (vba)
    Par Darkrems dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 17/09/2013, 12h37
  4. [WD12] Ajout d'enregistrements dans un fichier Hyperfile
    Par Falcon074 dans le forum WinDev
    Réponses: 2
    Dernier message: 04/11/2009, 14h18
  5. ajout espace vide(253) en fin d'enregistrement dans fichier
    Par carmella dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 01/06/2008, 19h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo