Datei-Version

Im Verlaufe der Weiterentwicklung eines Programms kann es durchaus einmal vorkommen, dass eine weiterentwickelte Version Ihres Programms die Daten anders in einer Datei ablegt als ihre Vorgängerversion. Wie die neue Programmversion trotzdem noch die 'alten' Dateien noch einlesen kann werden wir uns nun ansehen.

Betrachten wir uns zum Einstieg nochmals da Makro IMPLEMENT_SERIAL(...), so wie Sie es in den vorherigen Beispielen eingesetzt haben:

IMPLEMENT_SERIAL(CData,CObject,1);

Der letzte Parameter im Makro gibt die sogenannte Schema-Nummer an, die im Prinzip nichts anderes ist als eine Versionskennung der Datei. Diese Schema-Nummer wird mit in der Datei abgelegt. Wenn Sie nun eine neue Programmversion erstellen, die einen geänderten Datenaufbau besitzt, so können Sie durch hochzählen dieser Schema-Nummer der neuen Datei eine andere Versionsnummer mitgegeben. So ändert z.B. die folgende Anweisung die Versionsnummer der Datei auf den Wert '2':

IMPLEMENT_SERIAL(CData,CObject,2);

Wird nun versucht, eine alte Datei mit der Versionsnummer '1' einzulesen, so wird vom MFC-Rahmen standardmäßig folgenden Meldung ausgegeben und das Einlesen der Daten abgebrochen:

Falsche Dateiversion!

Um nun auch alte Dateiversionen einlesen zu können ist in der Anwendung das Makro IMPLEMENT_SERIAL(...) wie folgt anzupassen:

IMPLEMENT_SERIAL(CData,CObject,VERSIONABLE_SCHEMA | 2);

Durch ver-odern der Konstante VERSIONABLE_SCHEMA mit der aktuellen Versionsnummer wird die Ausgabe der obigen Meldung unterdrückt und die Methode Serialize(...) zum Einlesen/Abspeichern der Daten wie gewohnt aufgerufen. Innerhalb dieser Methoden kann dann durch den Aufruf der CArchive Methode GetObjectSchema(...) die Versionsnummer der einzulesenden Datei abgefragt werden. Als Returnwert liefert die Methode die Versionsnummer der geöffneten Datei die nun in der Serialize(...) Methode entsprechend ausgewertet kann.

Das folgende Listing zeigt einen Auszug aus einer entsprechend angepassten Serialize(...) Methode.

void CData::Serialize(CArchive & ar)
{
    if (ar.IsStoring())
    {
        // ZU ERLEDIGEN: Hier Code zum Speichern einfügen
        ....
    }
    else
    {
        // ZU ERLEDIGEN: Hier Code zum Laden einfügen
        ....
        int nVersion = ar.GetObjectSchema();
        ....
        if (nVersion != 2)
        {
            ::MessageBox(0,"Konvertiere Datei von V1.00 nach V2.00",
                         "HINWEIS", MB_OK|MB_ICONEXCLAMATION);
            m_fVar = float(0.0);
        }
        else
            ar >> m_fVar;
    }
}

Die Datenklasse CData ist im Beispiel irgendwann um das Datum m_fVar erweitert worden. Gleichzeitig wurde bei dieser Erweiterung die Dateiversion auf 2 hochgesetzt. Wird nun eine alte Datei mit der Versionsnummer '1' eingelesen, die das Datum m_fVar noch nicht enthält, so wird eine Meldung ausgegeben und das Datum m_fVar mit einem Standardwert initialisiert. Bei neueren Dateien wird das Datum richtig aus der Datei ausgelesen.

Es gibt noch eine weitere Methode SetObjectSchema(...) die es erlaubt, die aktuelle Versionsnummer umzusetzen.


Copyright © 2004

Senden Sie Emails mit Fragen oder Kommentaren zu dieser Website an: mailto:info@cpp-tutor.de
 Wolfgang Schröder, Lerchenweg 23, D-72805 Lichtenstein. Tel: +49 7129 6470