Unerwartetes Dateiformat


  • Mod

    Klar weil nun die Datei vorzeitig zu Ende ist.
    Du kanst nun die Daten vor dem Laden auf 0 setzen und die Exception abfangen und ignorieren

    try 
    {
    // Dein Serialisierungscode
    ...
    } 
    catch (CArchiveException *e)
    { 
    e->Delete();
    }
    


  • Noch eleganter geht es, wenn man die Versionierung gleich mit einplant:

    #define SCHEMA_VERSION_1        (0x1)
    #define SCHEMA_VERSION_2        (0x2)
    #define SCHEMA_VERSION_CURRENT  SCHEMA_VERSION_2
    
    IMPLEMENT_SERIAL(CTanke, CObject, VERSIONABLE_SCHEMA | SCHEMA_VERSION_CURRENT)
    
    // Serialisierung
    void CTanke::Serialize(CArchive& ar)
    {
        // Version abfragen
        int iSchema = ar.GetObjectSchema();
    
        // Version des Objekts ist groesser als die unterstuetzte
        if (iSchema > SCHEMA_VERSION_CURRENT && ar.IsLoading())
        {
            AfxThrowArchiveException(CArchiveException::badSchema);
        }
    
        // Laden
        if (ar.IsLoading())
        {
            // Version 1.x
            ar >> m_strString1; 
            ar >> m_strString2; 
    
            // Version 2.x
            if (iSchema >= SCHEMA_VERSION_2)
            {
                ar >> m_strString3; 
                ar >> m_strString4; 
            }
        }
    
        // Speichern
        else
        {
            // Version 1.x
            ar << m_strString1; 
            ar << m_strString2; 
    
            // Version 2.x
            ar << m_strString3; 
            ar << m_strString4; 
        }
    }
    


  • Spricht eigentlich was gegen etwas in der Art:

    void Serialize(CArchive& ar, String& str)
    {
        if (ar.IsLoading())
            ar >> str;
        else
            ar << str;
    }
    
    void CTanke::Serialize(CArchive& ar)
    {
        // Version abfragen
        int iSchema = ar.GetObjectSchema();
    
        // Version des Objekts ist groesser als die unterstuetzte
        if (iSchema > SCHEMA_VERSION_CURRENT && ar.IsLoading())
            AfxThrowArchiveException(CArchiveException::badSchema);
    
        // Version 1.x
        Serialize(ar, m_strString1);
        Serialize(ar, m_strString2);
    
        // Version 2.x
        if (iSchema >= SCHEMA_VERSION_2)
        {
            Serialize(ar, m_strString3);
            Serialize(ar, m_strString4);
        }
    }
    

    Ich habe das so selbst noch nie verwendet (ich mache nicht viel MFC, und noch weniger mit Serialisierung), bloss hab' ich mich immer gewundert wieso es in *keinem* der MFC Programme die ich bisher gesehen habe so gemacht wird.



  • Franz Hembera schrieb:

    #include "stdafx.h"
    
    			  m_strMehrwert >>
    			  m_strMehrwert >>
    }
    

    Bei Zeile 167



  • hustbaer schrieb:

    Spricht eigentlich was gegen etwas in der Art:

    void Serialize(CArchive& ar, String& str)
    {
        if (ar.IsLoading())
            ar >> str;
        else
            ar << str;
    }
    
    void CTanke::Serialize(CArchive& ar)
    {
        // Version abfragen
        int iSchema = ar.GetObjectSchema();
    
        // Version des Objekts ist groesser als die unterstuetzte
        if (iSchema > SCHEMA_VERSION_CURRENT && ar.IsLoading())
            AfxThrowArchiveException(CArchiveException::badSchema);
    
        // Version 1.x
        Serialize(ar, m_strString1);
        Serialize(ar, m_strString2);
       
        // Version 2.x
        if (iSchema >= SCHEMA_VERSION_2)
        {
            Serialize(ar, m_strString3);
            Serialize(ar, m_strString4);
        }
    }
    

    Ich habe das so selbst noch nie verwendet (ich mache nicht viel MFC, und noch weniger mit Serialisierung), bloss hab' ich mich immer gewundert wieso es in *keinem* der MFC Programme die ich bisher gesehen habe so gemacht wird.

    Nein, dagegen spricht nichts. Letztlich unterscheidet es sich von meinem Beispiel nur darin, dass die Serialisierung der verschiedenen Strings ausgelagert wird. Damit wird die Funktion selbst etwas übersichtlicher. Jeder Datentyp verlangt dann aber auch eine eigene Serialize-Funktion.

    Der Vorteil dieser Methode ist, dass bei Programmupdates die alten Dateien einfach übernommen werden können. Der andere Weg (alte Programme lesen neuere Dateien) ist aber fast unmöglich.

    Ich selbst habe diese Methode ziemlich oft verwendet, mittlerweile speichere ich aber nur noch in XML-Dateien.



  • Danke für Euere Postings. Habe das ganze umgestellt und bekomme jetzt vom Compiler eine Meldung wegen Stapelüberlauf, nachdem ich /Zm auf 2000 gesetzt habe. Meine Programmierkünste sind leider nicht so, dass ich damit grosse Sprünge machen kann. Vieles von dem, was so gepostet wird, verstehe ich nicht so recht.

    Habe das ganze Programm gelöscht und begnüge mich nun mit meiner ersten Version.

    Nochmals herzlichen Dank und Grüsse

    Franz


  • Mod

    Rebuild All bereits versucht?

    Warum verwendest Du /Zm? Ich habe diese Optionnoch nie benötigt, und meine Projekte sindnicht klein.



  • Beim Kompilieren kam die Meldung, dass die Dateien zu gross für den Compiler sind und ich /Zm verwenden soll. Der Maximalwert ist da 2000. Leider hat das auch nicht ausgereicht.

    Grüsse

    Franz



  • Versuchs mal mit /Zm800, bei grösseren Werten hab' ich schon Probleme gehabt. Bzw. spiel dich einfach mal ein wenig.
    Und... seit ich VC7.1 bzw. 8.0 verwende hab ich /Zm überhaupt nie mehr gebraucht.



  • Danke hustbaer, werde es mal probieren!

    Grüsse
    Franz


Anmelden zum Antworten