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 :

Problème d'écriture vers fichier binaire


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 8
    Points : 5
    Points
    5
    Par défaut Problème d'écriture vers fichier binaire
    Bonjour à tous.

    J'ai un petit problème qui concerne l'écriture d'un fichier sans altérer son contenu initial (à part la partie réécrite évidemment).
    Je cherche à réécrire (remplacer) au début du fichier une structure de taille 54 octets.
    Ca marche bien mais le souci c'est que je perd tout ce qu'il y a après.

    J'ai essayé avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ofstream FileOut;
    FileOut.open(nom_fic.c_str(), ios_base::binary); // Ouverture
     
    if ( FileOut.is_open() ) {
    	FileOut.write( reinterpret_cast<const char*>(&fh), sizeof(BMPFILEHEADER) );
    	FileOut.write( reinterpret_cast<char*>(&ih), sizeof(BMPINFOHEADER) );
     
    	FileOut.close();
    } else succes = false;
    Résultat : Ma structure est bien écrite pas de souci pour la relire ensuite, mais je me retrouve avec des fichiers de 54 octets en ayant perdu toute la suite

    J'ai essayé aussi un mode d'ouverture différent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    FileOut.open(nom_fic.c_str(), ios_base::ate); // Ouverture
    FileOut.seekp(0);
    Le mode "ate" sert apparament à ouvrir et se placer à la fin, donc en conservant le contenu, et seekp permet de se replacer au début du fichier.
    L'idée me paraissait bonne... résultat : 54 octets

    Comme les fichiers en question sont des bmp (plusieurs méga), j'aimerai bien
    éviter de devoir bidouiller en lisant tout pour réécrire tout !
    Quelqu'un a t-il une solution ?

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Peut-être refaire un seek pour te replacer à la fin avant le close() ?

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 8
    Points : 5
    Points
    5
    Par défaut
    J'ai ajouté :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    FileOut.seekp(0, ios_base::end);
    juste avant de fermer le fichier.
    Le résultat n'a pas changé !
    J'ai meme essayé de mettre directement la taille du fichier "en dur".

    Par contre si après m'être placé à la fin, j'écris un caractère, alors le fichier
    fait la bonne taille plus un caractère. Mais tout l'espace "sauté" par le seek, et qui devrait être le contenu initial est initialié à 0. Je le constate avec un éditeur hexa qui m'affiche ma structure au début, pleins de zéros, et le petit caractère à la fin...

  4. #4
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Le flag est censé être (ios_base::binary|ios_base::app).

    Dans le cas contraire, le fichier est ouvert en out+binary, ce qui corresponds selon la norme C++ au mode "wb" de fopen() (qui fait donc un truncate du contenu) au lieu de "ab" (pour faire un append).

    ios_base::ate se positionne à la fin du fichier, mais si le fichier est ouvert en mode "wb", cela ne fait pas grand chose. Il ne conserve pas le contenu.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 8
    Points : 5
    Points
    5
    Par défaut Presque...
    Effectivement je ne risquai pas d'y arriver...

    J'ai changé le flag pour : ios_base::binary|ios_base::app

    Le résultat est un peu plus proche de celui attendu, c'est à dire que le contenu est conservé. Tellement bien conservé d'ailleurs que mes fichiers gagnent 54 octets à chaque écriture...
    J'ai lu dans une doc que le mode "app" replace automatiquement le pointeur d'écriture à la fin du fichier avant chaque opération d'écriture. Ce qui explique que rien n'est écrasé puisque j'écris à la fin. J'aimerai donc bien qu'il reste au début...

  6. #6
    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
    prends un std::fstream plutôt qu'un std::ofstream et ne joue pas avec le mode d'ouverture. Si tu le dois, in|ou|ceux dont tu as besoin.

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2008
    Messages
    8
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 8
    Points : 5
    Points
    5
    Par défaut Ca marche !
    Effectivement, un simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fstream FileOut(nom_fic.c_str());
    marche très bien. Je n'espérai plus une solution aussi simple !
    Merci beaucoup !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 10
    Dernier message: 13/11/2008, 18h12
  2. UTL_FILE : problème d'écriture du fichier
    Par stepd dans le forum SQL
    Réponses: 3
    Dernier message: 31/01/2008, 17h42
  3. [VS2005]lecture/écriture dans fichier binaire
    Par shadowmoon dans le forum Windows Forms
    Réponses: 10
    Dernier message: 25/09/2007, 17h30
  4. Réponses: 5
    Dernier message: 26/03/2007, 01h30
  5. Réponses: 5
    Dernier message: 04/12/2006, 17h40

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