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:

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. |
|