Anwendung im nachhinein serialisierbar machen...



  • Hallo,
    ich habe eine dialog. Anwendung erstellt, welche nun auch noch Dateien öffnen können soll. Also brauch ich die Serialisierung, aber wie bekomm ich das im nachhinein hin, laut M&T VC++ in 21 Tagen Kap. 13 muß man das gleich am Anfang im Anwendungs-Assistenten auswählen!
    Weiß da jemand Rat??



  • Es geht auch im Nachhinein.

    Guck doch einfach mal, was der Unterschied zwischen einem leeren Projekt MIT und einem OHNE Serialisierung ist.

    Das überträgst du und fertig.
    🙂



  • Das Problem ist ja halt nur, dass ich bei einer dialog. Anwendung gar keine Serialisierung auswählen kann! Wie kann ich das trotzdem in meine Anwendung integrieren?? Das genua Problem ist folgendes: Es soll ein Konverter erstellt werden, welcher Daten aus einer CSV Datei einließt und binär speichert.
    Diese Daten sollen dann im Hauptprogramm gelesen und mit ihnen Berechnungen durchgeführt werden. Das ganze geht doch nur mit Serialisierung, oder??
    Bin für jeden Tipp dankbar!!
    Grüße Christian



  • Guck dir mal CStdioFile an.
    Damit kannst du schön einfach Dateien lesen und schreiben.

    Aber es gibt auch eine Lösung für Serialisierung für Dialoganwendungen.

    Die schreib ich bei Bedarf aber erst morgen.



  • Das Problem ist, die Datei soll binär, also nicht "menschlich" lesbar sein, also fällt CStdioFile flach. Es sollte schon per Serialisierung funktionieren. Das wär echt super wenn du mir das schreiben könntest, morgen reicht auch gut, hab eh gleich Feierabend 🙂
    Im Vorraus vielen Dank,
    Gruß Christian



  • So, moin erstmal!

    Das hier stammt aus dem Buch Visual C++6 (3-8266-0902-6) Ab Seite 291.

    Ich habe es nur grob zusammengefasst, sonst wäre es mir zu lang.

    Todos in der Datenklasse:

    Du musst DECLARE_SERIAL in den Header und IMPLEMENT_SERIAL in der Cpp eintragen. Die Klasse muss von CObject abgeleitet sein.

    Danach musst du die virtuelle Funktion Serialize überschreiben (geht per Assistent).

    Die sieht dann etwa so aus (kennst du bestimmt schon):

    void CKlasse::Serialize(CArchive& ar)
    {
      if (ar.IsStoring())
      { // Speichern
      }
      else
      { // Laden
      }
    }
    

    CArchive ist übrigens von CFile abgeleitet, also war CStdioFile gar nicht sooo daneben.

    Todos im Dialog:
    Ich habe mal die Speicherfunktion abgeschrieben:

    BOOL bCanSave = FALSE;
    
    UINT nFlags = CFile::typeBinary | CFile::ModeWrite;
    
    // Datei existiert nicht -> erstellen
    if (_access(DATA_FILE, 0))
    {
      nFlags |= CFile::ModeCreate;
      bCanSave = TRUE;
    }
    else
    {
      bCanSave = CanSerialize();
    }
    
    // Datei existiert und man kann Lesen/Schreiben
    if (bCanSave)
    {
      CFile file;
      CFileexception fe;
    
      if (file.Open(DATA_FILE, nFlags, &fe)
      {
        CArchive ar(&file, CArchive::store);
        Serialize(ar);
      }
    }
    

    So, ich hoffe das waren die Sachen, die du brauchst. Falls nicht kann ich ja nochmal blättern.

    Bye 🙂



  • Danke, das hilft mir schon mal etwas weiter, aber ein paar Fragen hab ich noch:
    wie bzw. geb ich den Dateinamen an, in den geschrieben bzw. aus dem gelesen werden soll??
    Und wenn ich eine .csv (also mit ; getrennt) Datei habe, wie kann ich diese dann einlesen und in eine binärcodierte Datei umwandeln?
    Z.B. steht in der ersten Zeile der Datei:
    Baum grün 28 Äste 56786 Blätter

    Jetzt sollte das ganze so in einer neuen Datei gespeichert werden, dass es nicht mehr direkt lesbar ist, ich aber auf alles zugreifen kann, also z. B. eine CString Var. für "Baum", eine int für "28" usw. habe.
    Ist bißchen schwer zu erklären, aber ich bin für jede Hilfe dankbar!

    Grüße
    Christian



  • Hmm, im Nachhinein fällt mir auch auf, dass da nie ein Dateiname auftaucht. Aber an der Stelle, wo er hingehört steht DATA_FILE - ersetz das mal.

    Die csv würde ich zeilenweise (CStdioFile) einlesen, an den Kommas (bei dir scheinen es ja Leerzeichen zu sein?) zerhacken und dann in die entsprechenden Variablen stecken und in das Archiv schreiben.

    Bye 🙂



  • Stimmt, das mit DATA_FILE hab ich auch grad rausgefunden. Ja, das war mein Fehler, sollten ; dazwischen sein.
    Okay, ich werd das ganze mal so probieren, vielen Dank!

    Grüße
    Christian



  • Ich wuerd mir Ueberlegen, ob Du wirklich die MS Strategie nutzen willst.

    Wenn man sie von anfang nutzt, ist sie sehr komfortabel, aber man baut seine Struktur halt schon nach dieser Anforderung auf.
    Ohne Serialisierung nutzt man meist auch andere strukturen ....

    Sind alle deine zu speichernden Objekte von CObject abgeleitet ?
    Benutzt du nur Container, die Serialisierung unterstuetzen ....

    Ich wuerd mich da eher Schwertun, aber vielleicht hast ja glueck ! :p
    Ich find ne sauber getrennte Daten und Ansichtstruktur mit eigener Serialisierung besser und vor allem flexibler.

    Ciao ...



  • Ich würde es schon gerne mit der Serialisierung probieren, es klappt auch schon etwas, nur hab ich noch folgendes Problem:
    Ich öffne meine .csv Datei mit folgendem Inhalt:
    baum;gruen;15;jahre;56789;blatter
    Mit file.ReadString kann ich das ja nun auch problemlos einlesen, und ich könnte ja auch immer die Stings zwischen den ; in Variablen schreiben und diese dann durch die Serialize Methode in eine Datei schreiben lassen:

    void CSerial::Serialize(CArchive &ar)
    {
    	if(ar.IsStoring())
    	{
    			ar <<m_string1, ar<<m_string2, ...;
    	}
    }
    

    nur gibt es da mehrere Probleme:
    Jedesmal, wenn ich Serialize() aufrufe, wird der vorherige Inhalt der Datei gelöscht, wenn ich also eine Quelldatei mit vielen Zeilen habe und ich diese per Schleife einlesen will, wird immer nur der aktuelle Durchlauf in der Zieldatei gespeichert. Und wie bekomm ich die einzelen Daten nachher wieder aus der binärdatei gelesen und kann sie wieder Variablen zuweisen???

    Ich bin ziemlich Ratlos! 😕

    Vielen Dank für eure Hilfe,
    Gruß Christian


Anmelden zum Antworten