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

MFC Discussion :

[MFC][CStdioFile] étrange comportement


Sujet :

MFC

  1. #1
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut [MFC][CStdioFile] étrange comportement
    bonjour à tous,

    j'ai un CStdioFile monFichier, et j'effectue diverses manipulations dessus:

    - Quand j'insère du texte, il n'y a pas de problème. Pour insérer, j'utilise la méthode suivante: je met tout le texte qu'il y a après le curseur dans un buffer, je concatène ce buffer sur la chaine que je veux insérer, puis j'écris brutalement le tout.
    - Quand je rajoute du texte à la fin du fichier, j'obtiens l'erreur Disk Full, alors que mon disque a plusieurs Go de libres.
    - Quand je remplace du texte situé en fin de fichier (la dernière ligne par exemple), je n'obtiens pas d'erreur mais le fichier n'est pas modifié. (je remplace, donc la taille du fichier n'est pas modifiée).

    Remarque: j'obtiens exactement la même chose en utilisant CFile à la place de CStdioFile. De même, les résultats sont identiques que j'utilise la fonction CFile::Write() ou CFile::WriteString().

    on a passé plusieurs heures là-dessus déjà, et on est bloqué. Si quelqu'un a une idée

    merci par avance

  2. #2
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    salut,
    heum heum ,montre ton code ....

  3. #3
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Ok, tu l'aura voulu

    J'ai donc une classe MonFichier qui hérite de CStioFile. Voici la fonction qui pose problème:
    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
    MonFicher::remplaceDerniereLigne(CString buffer)
    {
    	// d'abord, je me positionne au bon endroit, c'est à dire au début de la dernière ligne:
    	SeekToEnd();
    	char c='0';
    	ULONGLONG dwPos = GetPosition();
    	while (c!='\n')
    	{
    		Seek(--dwPos,CFile::begin);
    		Read(&c,1);	
    	}
     
    	//ensuite, j'écris mon buffer:
    	try
    	{
    		Write(buffer, buffer.GetLength());
    	}
    	catch (CFileException *e)
    	{
    		e->ReportError();
    		e->Delete();
    		return 1;
    	}
    	return 0;
    }
    Donc:
    1/ si la ligne a remplacer est + grande -> exception: disk full
    2/ si la taille est strictement identique -> il ne se passe rien (le fichier n'est pas modifié et je n'ai aucun message d'erreur).

    Remarque: j'ai une methode MonFichier::Insert qui fonctionne exactement de la même façon, mais qui fonctionne très bien:

    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
    int MonFichier::insert(CString strStringToInsert)
    {
    //quand on apelle cette fonction, on est déjà positionné au bon endroit dans le fichier
    	ULONGLONG dwPos = GetPosition();
    	CString strBuffer = strStringToInsert;
     
    	int iErr = 1;
    	char c = '0';
    	while (iErr!=0)
    	{
    		iErr = Read(&c,1);
    		if (iErr!=0)
    			strBuffer+=c;
    	}
     
    	Seek(dwPos, CFile::begin);
     
    	try
    	{
    		Write(strBuffer, strBuffer.GetLength());
    	}
    	catch (CFileException *e)
    	{
    		e->ReportError();
    		e->Delete();
    		return 1;
    	}
     
    	return 0;
    }

  4. #4
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    ah oui, un petit détail: quand je déb(u)(o)g(g)(u)()e en mode pas à pas (avec F10), il se passe quelque chose d'étrange. C'est dans le cas où le fichier n'est pas modifié:
    j'arrive à la ligne du catch.
    il se positionne sur l'accoladeouvrante.
    Il va direct à l'accolade fermante.
    Il revient sur le return 1 (la ligne juste avant l'acolade fermante).
    Il repart sur la ligne après l'accolade fermante.
    Il continue normalement.

    Est-ce normal??

  5. #5
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    montre l'ouverture du fichier ,pour travailler comme ça il faut etre en mode binary et pas en mode texte .

  6. #6
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par farscape
    montre l'ouverture du fichier ,pour travailler comme ça il faut etre en mode binary et pas en mode texte .

    En effet, je l'ouvre en mode Texte (flag CFile::typeText)!!! Mais pourquoi ma fonction insert fonctionne et pas l'autre???

  7. #7
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Rhaaa, je viens de changer (typeText -> typeBinary), mais ça ne change rien...

  8. #8
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    re,
    montre ton ouverture ...
    note: au cas ou on insert pas dans un fichier mais on ecrase ...
    la notion d'insertion n'existe pas il faut se la faire.

  9. #9
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    MonFichier *m_rfFile;
    if (m_rfFile->Open(strFileName, CFile::modeReadWrite | CFile::typeBinary)==0)
    {
    	return 2;
    }
     
    int iErr = m_rfFile->remplaceDerniereLigne("toto");
    je viens de voir quelque chose de surprenant: dans mon code de remplaceDerniereLigne, si j'enleve la boucle qui sert à revenir au début de la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ULONGLONG dwPos = GetPosition(); 
       while (c!='\n') 
       { 
          Seek(--dwPos,CFile::begin); 
          Read(&c,1);    
       }
    ça marche!! Sauf que ça m'ajoute mon texte au mauvais endroit bien sûr...

  10. #10
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par farscape
    note: au cas ou on insert pas dans un fichier mais on ecrase ...
    la notion d'insertion n'existe pas il faut se la faire.
    ouioui, je sais. J'ai mis le code de ma fonction Insert au début du post. Elle fonctionne bien elle :/

    Mais j'ai un doute quant à ma méthode pour insérer du texte.
    Ne serait-ce point plus propre et prudent de faire comme ça:
    1/ récupérer tout le fichier
    2/ on détruit le fichier
    3/ on prépare notre buffer
    4/ on recré le fichier et on y met notre buffer.

    Qu'en pensez-vous?

  11. #11
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    dans de l'ecriture sur la fin de ligne il faut tronquer le fichier a zero et ecrire la nouvelle ligne:
    exemple extrait brut de fonderie:
    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
     
      int nMode=CFile::modeCreate | CFile::modeNoTruncate | CFile::typeBinary | CFile::modeReadWrite | CFile::shareDenyNone;
        m_FleJrn.Open( strFileJrn,nMode, &m_e);            
        m_FleJrn.SeekToEnd();
        char c='\n';
        while(c=='\n' || c=='\r')
        {
            m_FleJrn.Seek(-2,CFile::current);
            m_FleJrn.Read(&c,1);
        }
        c=0;
        while(c!='\n' && c!='\r')
        {
            m_FleJrn.Seek(-2,CFile::current);
            m_FleJrn.Read(&c,1);
        }
        m_FleJrn.SetLength(m_FleJrn.GetPosition());
        CString str="essai\r\n";
        m_FleJrn.Write(str,str.GetLength());    
        m_FleJrn.Close();
    sinon dans le cas de modification de fichier je pense qu'il est preferable d'utiliser CFile en mode binaire.

  12. #12
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    merci farscape :o)

    Juste une précision, il faut ajouter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_FleJrn.SetLength(m_FleJrn.GetPosition());
    après le Write, sinon le fichier est tronqué et le Write ne sert à rien (j'ai testé)

    encore merci et... à bientôt

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

Discussions similaires

  1. TFlowPanel étrange comportement
    Par Peck777 dans le forum Composants VCL
    Réponses: 0
    Dernier message: 11/02/2009, 15h42
  2. Raccourci sur touche F10 - étrange comportement
    Par hulahup dans le forum Windows Forms
    Réponses: 5
    Dernier message: 22/04/2007, 12h12
  3. RequestDispatcher, étrange comportement
    Par hel22 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 22/02/2007, 15h33
  4. Réponses: 11
    Dernier message: 20/03/2006, 14h42
  5. [MFC] étrange comportement de DoModal()
    Par r0d dans le forum MFC
    Réponses: 11
    Dernier message: 15/06/2005, 19h53

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