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

Langage C++ Discussion :

fstream et close()


Sujet :

Langage C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 96
    Par défaut fstream et close()
    Bonjour,

    J'ai développé une architecture Client/Serveur de transferts de fichiers, grosso modo. Lorsque le client reçoit les données envoyées par le serveur, un fichier est ouvert en écriture. Pour ouvrir ce fichier, je passe par la classe ofstream. Un problème survient lorsque le client ferme ce fichier via la méthode close() : Il semblerait qu'il s'agisse en fait d'une exception. J'ai tenté un try{}catch{}, mais je n'ai pas réussi à relever cette exception, le code à l'intérieur du catch{} n'ayant pas été lu (?).

    Ce qui me dérange, c'est que cela semble survenir aléatoirement :
    • Lorsque j'exécute l'application sans le mode débogage
    • Lorsque le client effectue sa deuxième demande de transfert : Lors de la première demande, tout se déroule bien... je n'ai pas de rapport de Visual Studio (VS). Lors de la seconde demande de transfert concernant le même fichier, l'application plante. VS désigne une exception win32 non gérée.


    Je ne comprends pas vraiment ce qui cloche. Je ne déclare qu'une fois mon ofstream, l'ouvre et le referme quand il le faut... conditions sans lesquelles, aucun essai n'aurait le résultat escompté. Ce comportement m'échappe vraiment.

    Auriez-vous quelque(s) suggestion(s) ?

    Il semblerait que le même soucis survienne avec l'utilisation de FILE *, toujours au moment de la fermeture du fichier (fclose()). Le problème me parait complètement bizarre, d'autant plus qu'il arrive vraiment trop aléatoirement maintenant : au premier transfert, ou au second, ou au troisième, ou...
    Je n'arrive pas à attraper l'exception. Le débogueur m'indique une "violation d'accès lors de la lecture". Je ne vois pas de quoi il s'agit, et surtout je ne vois pas pourquoi ça marcherait parfois seulement...

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Une exception Win32 n'est pas nécessairement une exception C++ (même si la réciproque est vraie sous Visual), et n'est donc (normalement) pas interceptée par un try/catch.

    Pour le reste, on ne peut pas trop t'aider sans le code.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 96
    Par défaut
    J'ai deux types de traitement d'écriture dans des fichiers. Je me sers d'ofstream pour le premier, qui correspond à une écriture binaire. Le second fait appel à FILE* pour une écriture en texte.

    J'ai une boucle d'écoute dans laquelle j'ai développé les processus d'écriture. C'est donc dans cette boucle que je vais utiliser ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ofstream of;
    FILE * pFile;
    Les déclarations sont faites en dehors de la boucle. A l'intérieur de la boucle, j'ouvre ou créer les fichiers un à un, et les remplis séquentiellement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    //nomFichier est de type const char*
    of.open(nomFichier, ios::out | ios::binary);
    pFile = fopen(nomFichier, "w");
    Je ne les ouvre pas en même temps, je m'y prend comme ceci (je passe sur la réception des données dont j'ai besoin) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SI typeFichier est binaire
         of.open(nomFichier, ios::out | ios::binary);
         SI tailleFichier > 0
              TQ nombreOctetsRec < tailleFichier
                   /* ... Traitement de réception
                           et d'écriture dans le fichier ... */
              FTQ
         FSI
         of.close();
    FSI
    Je fais exactement la même chose avec FILE*.

    A chaque fois que le problème est survenu, cela venait de of.close() ou bien de fclose(pFile).

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Je sais que si fopen() a échoué, il ne faut pas faire de fclose().
    Mais pourquoi ne pas utiliser un ofstream texte pour le second fichier ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 96
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Je sais que si fopen() a échoué, il ne faut pas faire de fclose().
    Je n'ai pas eu de rapport d'erreur ciblant fopen(). J'ai tenté ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    pFIle = fopen(nomFichier, "w");
    if(pFile != NULL)
    {
         /* ... Traitements ... */
    }
    else AfxMessageBox("/* rapport d'erreur*/");
    L'application n'a jamais affiché le rapport d'erreur au cours de mes différents tests.

    Citation Envoyé par Médinoc Voir le message
    Mais pourquoi ne pas utiliser un ofstream texte pour le second fichier ?
    J'avais utilisé un ofstream au départ mais même avec un buffer bien initialisé, j'avais une taille de fichier, au niveau du client, qui ne correspondait pas à la taille de fichier au niveau du serveur. J'avais initialisé le buffer avant chaque réception d'un bloc de données, mais le problème persistait.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Entre un poste Unix et un poste Windows, tu n'es pas censé avoir la même taille lors d'un transfert texte (genre FTP en mode ASCII).
    Seul un transfert binaire est supposé donner deux fichiers identiques.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 96
    Par défaut
    Bonjour,

    Le problème persiste ce matin. Je ne vois vraiment pas ce qui cloche...

    Rappel du problème : Une exception win32 survient lorsque je fais appel à fclose() ou close() de fstream. Le débogueur m'indique qu'à ce moment précis du code, je viole un accès en lecture mais très franchement, je ne vois pas comment.
    Lorsque j'exécute l'application en mode débogage, tout se passe très bien. Aucune exception, aucun problème de fermeture d'un quelconque fichier...

    Auriez-vous quelques idées ?
    D'avance merci.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 96
    Par défaut
    Après plusieurs tests et manipulations du code, il semble que le phénomène est très clairement aléatoire... Cela ne marche pas parfois seulement : C'est à devenir dingue, tout simplement.

    Lorsque l'appel à fclose() ou à close() génère une exception, le contenu du fichier a auparavant été correctement rempli.

    Je pense avoir tenté tout ce que je pouvais, dans les limites des bornes de connaissances qui sont les miennes.

    Quelles raisons pourraient empêcher le bon déroulement de la fermeture d'un fichier ?

  9. #9
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Peut être que le problèmle est ailleurs et que ton exception n'en est que le révélateur.

    Peut être des buffer dans lesquels tu écris trop loin et cela met à mal les structures gérées par le noyau et cela se voit à la fermeture du fichier.

    Il va falloir chercher, regarder le code, utiliser un truc genre valgrind ou purify pour en être sûr.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

Discussions similaires

  1. [JDBC] java.sql.SQLException: Closed Statement
    Par cmoulin dans le forum JDBC
    Réponses: 4
    Dernier message: 03/09/2004, 17h22
  2. Violation d'accès apres Close
    Par SegmentationFault dans le forum Bases de données
    Réponses: 3
    Dernier message: 05/07/2004, 16h46
  3. [debutant][bdd] pb avec resultSet is closed
    Par mexong dans le forum JDBC
    Réponses: 5
    Dernier message: 22/03/2004, 16h42
  4. Utilisation de x.close et set x=nothing
    Par kayser dans le forum ASP
    Réponses: 3
    Dernier message: 05/12/2003, 08h49
  5. Réponses: 8
    Dernier message: 21/11/2003, 18h38

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