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

 C++ Discussion :

Ecrire des données tout le temps sur la première ligne d'un fichier


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Avril 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 16
    Points : 13
    Points
    13
    Par défaut Ecrire des données tout le temps sur la première ligne d'un fichier
    Bonjour, petite question C++: je dois persister une donnée (string) dans un fichier assez frequemment dans mon programme, mais je voudrais remplacer à chaque fois l'ancienne donnée par la nouvelle, donc si possible, avoir un fichier d'une seule ligne, et ecraser à chaque fois l'ancien contenu par le nouveau.

    Etant donné que le processus d'écriture doit se faire très souvent, il n'est pas vraiment question d'ouvrir et de fermer le fichier à chaque fois car c'est trop lent.

    De plus, je ne peux pas écrire la donnée uniquement à la fin de mon programme, car il faut impérativement qu'en cas de crash, le fichier contienne la derniere donnée en date.

    Grosso modo, pouvoir ouvrir mon fichier, ecrire ma donnée, revenir en début de fichier et réecrire par dessus.

    Y a t'il des moyens de faire cela ? Merci beaucoup !!

  2. #2
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Salut,

    Tu peux te baser sur cette page pour faire des tests d'utilisation de seekp notamment, qui devrait t'aider.

  3. #3
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par donquichotte Voir le message
    De plus, je ne peux pas écrire la donnée uniquement à la fin de mon programme, car il faut impérativement qu'en cas de crash, le fichier contienne la derniere donnée en date.
    Il faudra au minimum faire un flush() pour écrire le contenu du buffer sur le disque. Et encore, je ne suis pas sur qu'en cas de crash le fichier soit valide s'il n'a pas été fermé, quelqu'un a un avis ?

  4. #4
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Je crois qu'en cas de crash on a un état indéterminé pour le fichier... Comme le chat de Schrödinger

  5. #5
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    On pourrait peut-être imaginer un système avec deux processus (processus, hein, pas threads) :
    • le processus principal (ton programme tel qu'il est aujourd'hui, donc)
    • un processus secondaire mémorisant la valeur de ta string

    Le processus principal, au lieu d'écrire dans un fichier, envoie la valeur à mémoriser au processus secondaire.
    Le processus secondaire surveille le processus principal à la façon d'un watchdog. Dés que le processus principal ne répond plus, pouf, on écrit dans le fichier et on ferme.
    Sachant que ce second programme ne ferait que ça, il serait plus safe.

    Bon, évidemment on a toujours le risque que l'ordinateur soit éteint à l'arrache ou que l'OS se plante…


    Citation Envoyé par Alp
    Je crois qu'en cas de crash on a un état indéterminé pour le fichier... Comme le chat de Schrödinger
    Toutes ces fois où j'ai fait de la physique quantique sans m'en rendre compte…
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Florian Goo Voir le message
    Le processus secondaire surveille le processus principal à la façon d'un watchdog. Dés que le processus principal ne répond plus, pouf, on écrit dans le fichier et on ferme.
    Ou sauvegarder régulièrement en cas de changement (par expl ttes les secondes si le tps de sauvegarde<1s), ou dès que la valeur change en ayant un dbl buffer valeur en cours de sauvegarde/dernière valeur modifiée.

  7. #7
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Sylvain Togni Voir le message
    Il faudra au minimum faire un flush() pour écrire le contenu du buffer sur le disque. Et encore, je ne suis pas sur qu'en cas de crash le fichier soit valide s'il n'a pas été fermé, quelqu'un a un avis ?
    flush va transmettre a l'OS. Il faut des connaissances sur l'OS pour faire plus (fsync sous Unix par exemple, mais il faut un file descriptor qu'il n'est pas encore possible d'optenir de maniere conforme).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  8. #8
    Membre à l'essai
    Inscrit en
    Avril 2006
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 16
    Points : 13
    Points
    13
    Par défaut
    Merci pour vos réponses ! Comme je vois que vous poussez la reflexion assez loin, je me dois de vous donner quelques précisions :

    La sauvegarde de la donnée correspond à un message qui est reçu par mon programme, messages qui arrivent de façon totalement aléatoire (mais parfois avec des fréquences très élevées), et il faut vraiment que je fasse en sorte de sauvegarder le dernier reçu.

    Donc une sauvegarde faite selon une période cyclique ne correspond pas à ce que je recherche.


    Je fais pour les moments quelques tests et me contentant d'un fseek, sans flush et en ne fermant le fichier qu'en cas d'arrêt normal, et je reflechi à la façon d'implémentation la solution de Florian.

    Merci encore pour vos réponses !

  9. #9
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par donquichotte Voir le message
    Je fais pour les moments quelques tests et me contentant d'un fseek, sans flush et en ne fermant le fichier qu'en cas d'arrêt normal,
    Sans flush, il y a toute les chances qu'au moins une partie de ton message ne soit jamais transmit a l'OS -- sans parler d'arriver sur le disque.

    Un flush devrait le rendre plus robuste a un arret intempestif du programme, sans le rendre robuste a un crash de la machine.

    Un flush + qqch de specifique a l'OS du genre fsync le rendrait plus robuste aussi dans le cas d'un arret intempestif de la machine.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut pour infos
    open permet d'ouvrir les fichiers avec le flag O_SYNC qui force les écritures disque synchrones.
    De même, pread et pwrite permettent de lire/écrire nbytes à partir de l'offset donné en paramètre.

    Pour revenir avec la question posée, ce n'est pas parce qu'on demande via flush ou fsynch (ou pwrite) à l'OS une écriture disque synchrone que les données seront récupérables en cas de crash.

    Il faudrait pour ce faire que l'opération soit "atomique" ce qui n'est pas garanti: en fonction de la taille de l'IO et de l'allocation des blocks disques, cela pourra induire plusieurs opérations d'écriture et donc, une inconsistance "potentielle".

    La corruption est relativement simple à détecter puisqu'on peut associer un checksum ou un check byte aux données écrites. Pour ce qui est de la récupération, ie utiliser le dernier message "bien écrit", cela peut être simple dans le cas ou la taille des messages est bornée ou tortueux si elle doit être "variable".
    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Membre éclairé
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Points : 858
    Points
    858
    Par défaut
    Sinon, ce que tu peux faire c'est un système similaire à un monostable redéclenchable :
    Tu envoies ta chaîne à un objet qui va lancer une temporisation. L'objet ne sauvegardera dans un fichier que lorsque la temporisation arrivera à son terme. Si une nouvelle chaîne est transmise à l'objet, la temporisation est réinitialisée. Ainsi, la fréquence maximale d'écriture dans le fichier sera fixée par la durée de cette temporisation.

    Autre moyen d'optimisation : écrire sur le fichier seulement lorsque la valeur à écrire est différente de celle déjà contenue dans le fichier.
    Si ton programme est le seul processus à écrire dans ce fameux fichier et que la valeur de la chaîne à mémoriser ne change pas forcément à chaque fois que ton programme reçoit un message de l'extérieur, cela peut être assez efficace.
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  12. #12
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Tu peux faire ce que tu veux... flush, close, ou n'importequoi....

    En cas de coupure de courant, rien n'oblige le disque final a avoir réellement écrit les données... Les caches sont ainsi faits....
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par nicroman Voir le message
    Tu peux faire ce que tu veux... flush, close, ou n'importequoi....

    En cas de coupure de courant, rien n'oblige le disque final a avoir réellement écrit les données... Les caches sont ainsi faits....
    Tout comme on s'assure que l'OS écrive ses caches, on peut aussi s'assurer que disques et contrôleurs travaillent dans le même sens en:
    - désactivant les "writeback caches",
    - avec des batteries qui permettent aux caches de survivre aux pannes de jus.
    - en sécurisant le tout avec des disques en mirroir "logiciels" (attachés à des contrôleurs différents).

    Ceci dit, ces précautions (tant matérielles que logicielles) n'ont d'intérêt qu'à condition de pouvoir contrôler à postériori que les précieuses données ont été correctement écrites et la définition d'un mécanisme de reprise lorsque ce n'est pas le cas.

    -W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  14. #14
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Je ne veux pas apporter de solution par cette intervention, mais bel et bien ouvrir une autre manière de concevoir le problème...

    Quelque part, je me demande si tu ne cherche pas la complication là où elle n'a pas *forcément* lieu d'être.

    En effet, le fait que tu parle d'écrire l'information sur une ligne *semble* indiquer que cette information est, en terme de taille, relativement restreinte.

    Dés lors, ne crois tu pas que tu risque bien plus de "flinguer" les performances qu'autres choses en te basant sur le fait d'aller "relire" cette information chaque fois que tu en as besoin au lieu de la "maintenir en mémoire" dans une variable dédiée à cet effet

    Cette question est justifiée par le fait que l'accès à des données écrites sur le disque est sans doute l'acces le plus lent que l'on puisse envisager, sur un ordinateur, et que tu précise que l'écriture se fera souvent...

    De là à se dire que le besoin de récupérer cette information apparaitra de manière presque aussi récurrente, il n'y a qu'un pas (que je franchis peut être trop vite)

    Ne serait-il donc pas intéressant / opportun de restreindre l'utilisation du fichier à ce à quoi il peut réellement servir, à savoir: permettre la récupération de l'information lorsque l'application est relancée - quelle que soit la raison pour laquelle elle a été arrêtée - et / ou permettre d'avoir une trace de l'activité

    Tout cela nous emmène à une conclusion:

    Cela ne poserait, de prime abord, que bien peu d'inconvénients si l'inormation n'était pas écrite de manière systématique sur la première ligne du fichier:

    Tant l'utilisateur qui lirait le fichier que l'application sauraient qu'ils doivent aller "à la dernière ligne" pour obtenir la dernière information probante en date, rien n'empêchant l'application de recréer un fichier vide après récupération de cette information (au lancement).

    Après, il est toujours temps de s'inquiéter de l'opportunité d'écrire l'information en question, et là, tu peux soit envisager de le faire sur l'évenement atexit, soit envisager d'écrire toute information qui arrive à l'application, mais, ca, ca reste ton choix personnel

    Évidemment, si tu dois gérer le fait que l'application puisse être quittée sans lancer l'énévement atexit (en cas de coupure de courent, par exemple), il est sans doute préférable de prévoir l'écriture systématique de l'information, même si cela ne donne pas vraiment la certitude de pouvoir récupérer la "dernière information réelle"
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Ecrire des données sur XML
    Par SpencerX dans le forum Android
    Réponses: 1
    Dernier message: 07/01/2013, 23h56
  2. lire et ecrire des donnée dans un .ini
    Par gsmdu62 dans le forum Delphi
    Réponses: 6
    Dernier message: 25/05/2006, 03h29
  3. [DREAMWEAVER8] Envoyer des données d'un formulaire sur mail
    Par steeves5 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 21/02/2006, 18h15
  4. mise à jour des données toutes les semaines...
    Par Toff !!!!! dans le forum Access
    Réponses: 20
    Dernier message: 22/12/2005, 11h38
  5. [TextField] taper des chiffres...tout le temps...
    Par Piolet dans le forum Composants
    Réponses: 5
    Dernier message: 12/04/2005, 10h12

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