Datensätze speichern, ohne Datenbank oder Ini Datei

LaciFux

Grünschnabel
hallo,

bräuchte mal eine möglichkeit in der ich mithilfe von c++ (vs2005) lanfristig daten zu meinem programm speichern kann. am besten in einer datei, diese datei aber nicht unbedingt in klartext zu lesen sein soll (wie z.b. ini datei). ebenfalls soll keine datenbank genutzt werden, da dies wiederum zu viel aufwand wäre (xamp usw. + sql programmierung). habe das etwas von "records" gehört und in der mfc gibt es auch eine crecordset klasse. in wie fern kann ich das nutzen und/oder gibt es eventuell etwas besseres.

vielen dank im voraus... lacifux :confused:
 
Die CRecordset-Klasse wird mit Datenbanken verwendet, ist also nichts für dich, da du keine verwenden willst.
Du könnstest dir stattdessen mal die Klasse CArchive anschauen, mit der du Objekte serialisieren kannst. Da die Daten in binärer Form gespeichert werden, sind die Dateien auch nicht mehr ohne weiteres lesbar.

Gruß
MCoder
 
Hatte ich schon nachgesehen. Mein Problem ist, dass ich die Daten strukturiert reinschreiben und auch wieder lesen muss (wie in Ini Datei). Eine Ini Datei wäre prinzipiell ok, allerdings reichen mit die Möglichkeiten zur Datenkapselung nicht aus (Section, Key, Value).
In CArchive habe ich solche Möglichkeiten zur Strukturierung nicht erkennen können. XML hatte ich kurz überlegt, bietet aber auch keine einfache Möglichkeit zur Codierung der Daten. Irgendetwas muss es doch da geben. Mir fehlt sowas wie eine Ini Datei, in welcher ich eine Section noch weiter unterteilen kann als nur in Key.

Vielen Dank für die Antwort. Ich beschäftige mich nochmal mit CArchive. Vielleicht gibt es da ja eine Lösung.

LaciFux
 
XML kann man aber schon als so eine Art Erweiterung von INI Dateien nutzen. Jedenfalls kann man in einer XML Datei verschiedene Elemente mit Attributen anlegen. Kann mir vielleicht jemand etwas genaueres dazu sagen?!

LaciFux
 
Noch mal zum Thema CArchive: Da du ja ganze Objekte serialisieren kannst, musst du eine gewünschte Struktur in diese Objekte packen. Ist eigentlich recht easy, allerdings nicht besonders portabel, da es nur mit der MFC funktioniert.

XML halte ich für eine gute Lösung, da man die Daten sehr viel besser strukturieren kann, als etwa mit einer INI-Datei. Ansonsten weiß ich nicht, was man Genaueres dazu sagen soll. Schaue dir einfach mal den Aufbau einer beliebigen XML-Datei an, dann dürfte das Prinzip schon klar werden. Allerdings sind XML-Dateien wieder Textdateien, womit sie dann auch wieder im Klartext lesbar wären.

Gruß
MCoder
 
Das mit CArchive hört sich gut an. Wenn ich das so verstandenhabe:

1. Anlegen einer Struktur, welche meiner Vorstellung entspricht:

typedef struct{
int nID;
CString m_Name;
CString m_Address;
} STORAGE;

2. Object erzeugen

STORAGE myStorage;

3. Instanz von STORAGE archivieren

CArchive myArchive(..., myStorage, ...);

Ist das so ungefähr gemeint? Programmiere übrigens MFC aber erst seit gut einem Monat und habe mich von daher noch nicht so gut mit der Dokument / Ansicht Struktur vertraut gemacht. Falls das so wie oben funktionieren sollte, ist noch die Frage wie ich das lesen kann, wenn meine Member (z.B. die CString Member) teilweise variable Länge haben. Weiß nicht genau wie der sizof Operator (z.B. sizeof(CString)) macht.

Hoffe erschlage Dich nicht MCoder. Vielleicht kennst Du Dich ja damit aus!

LaciFux
 
Die serialisierbaren Klassen müssen entsprechend vorbereitet werden. Ich hoffe, anhand des kleinen Beispiels wird das einigermaßen klar. Wichtig ist Ableitung von der Klasse CObject und die Verwendung der Makros DECLARE_SERIAL und IMPLEMENT_SERIAL.
C++:
//////////////////////////////////////////////////////////////////////////
// Serialisierbare Klasse

class MyData : public CObject
{
public:
    CString m_str;
    int     m_nNumber;
    double  m_dDouble;

    virtual void Serialize( CArchive& ar )
    {
        if( ar.IsStoring() )
        {
            ar << m_str;
            ar << m_nNumber;
            ar << m_dDouble;
        }
        else
        {
            ar >> m_str;
            ar >> m_nNumber;
            ar >> m_dDouble;
        }
    }

    DECLARE_SERIAL(MyData)
};

C++:
IMPLEMENT_SERIAL(MyData, CObject, 1)

//////////////////////////////////////////////////////////////////////////
// Schreiben

CFile fileOut;

if( fileOut.Open(_T("c:\\temp\\mydata.dat"), CFile::modeCreate | CFile::modeWrite) )
{
    CArchive arOut(&fileOut, CArchive::store);

    MyData mydata;
    mydata.m_str     = _T("String");
    mydata.m_nNumber = 1;
    mydata.m_dDouble = 2.2;

    mydata.Serialize(arOut);
    arOut.Flush();

    fileOut.Close();
}

//////////////////////////////////////////////////////////////////////////
// Lesen

CFile fileIn;

if( fileIn.Open(_T("c:\\temp\\mydata.dat"), CFile::modeRead) )
{
    CArchive arIn(&fileIn, CArchive::load);
    
    MyData mydata;
    mydata.Serialize(arIn);
    arIn.Flush();

    fileIn.Close();

    cout << (LPCTSTR)mydata.m_str << endl
         << mydata.m_nNumber      << endl
         << mydata.m_dDouble      << endl;
}
Gruß
MCoder
 
Ich danke Dir wirklich MCoder für Deine Zeit und Bemühen. Werde Deine Variante testen und hoffe oder denke das sie funktionieren wird. Hätte nur noch eine kleine Frage bezüglich der Daten im "Archiv". Sind diese persistent, also bleiben sie auch nach Programmende im Festplattenspeicher erhalten und können beim nächsten Aufruf genutzt werden?! Vielleicht interessieren sich ja auch noch mehr User für das Thema.

Viele Grüße und besten Dank an Dich...

LaciFux
 
Die Daten werden ja in eine Datei geschrieben (mydata.dat im Beispiel) und sind damit natürlich persistent.

Gruß
MCoder
 
Zurück