Serialisieren

  • VB.NET

Es gibt 60 Antworten in diesem Thema. Der letzte Beitrag () ist von phil.

    Serialisieren

    Dieses Thema hat sich zu einer Diskussion über verschiedene Serialisierer entwickelt.
    Ein Serialisierer ist eine Funktion, die ein Objekt in einen Stream schreiben kann und umgekehrt.
    Hier eine Übersicht über die Serialisierer, über die gesprochen wurde:

    XML-Serializer
    sharpSerializer
    binaryFormatter
    + ist vom Menschen lesbar (xml-Format)
    - kann keine Dictionarys/generische Typen serialisieren
    - kann keine 2undMehrD-Arrays serialisieren
    - eine dll muss importiert werden
    - serialisiert nur Propertys
    - dadurch werden Arrays kompliziert
    - ist nicht vom Menschen lesbar(nur Byte-Code)
    + kann Dictionarys/generische Typen serialisieren
    + kann 2D-Arrays serialisieren





    Hallo erstmal

    ich habe ein Spiel programmiert (ähnlich, wie Schach, nur komplizierter ;) ), bei dem ich gerne den Spielstand speichern kann, um später weiterzuspielen.
    Eigentlich muss ich nur ein Objekt (mit Objekten innerhalb), genannt "world" abspeichern.
    Dafür würde ich gerne eine eigene Dateiendung verwenden. - Wie geht das?

    Ich habe bereits die Forumsuche und Google ausgequetscht. Meine Funde:
    - wie man eine Dateiendung registriert - kann man doch auch händisch in Windows machen
    - viele Probleme bei Details
    Was ich nicht gefunden habe:
    - wie man eine eigene Dateiendung überhaupt benutzt --> Speichern/Öffnen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „phil“ () aus folgendem Grund: Übersichtlichkeit

    Beim Registrieren einer Dateiendung wird Windows lediglich mitgeteilt, welches Programm gestartet werden soll. Die Datei, besser gesagt, den Pfad der Datei, bekommt Dein Programm als CommandLine-Argument mitgeliefert. Hier solltest Du ansetzen.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Suche im Forum nach Dateiendung registrieren.
    1. Treffer.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ob du eine eigene Dateiendung dafür nutzt ist völlig wayne. Die Endung hat mit dem Inhalt erstmal gar nichts zu tun. Die Endung ist nur für Windows gut, damit Windows weiß mit welchem Programm sie geöffnet werden soll. Das Format, kannst du also völlig frei wählen, wie es dir am Sinnvollsten erscheint.

    z.B. jedes Objekt bekommt eine Nummer und dann die Koordinaten

    Quellcode

    1. {34:4,3}{3:6,2}{6:8,10}


    oder als XML Datei, da gibts hunderte Möglichkeiten die dir ausdenken kannst.

    Was aufjedenfall nicht geht, was du vlt. vermutest, das einfach sowas wie Spielfeld.Save("savegame.dat") gibt. Also du musst den Speicherungsalgorithmus schon selbst schreiben und ebenso das Laden.

    Dodo schrieb:

    du musst den Speicherungsalgorithmus schon selbst schreiben und ebenso das Laden
    Wenn die Daten bereits in einer eigenen Struktur (Objekt, Structure...) vorliegen, könnte man diese Struktur per XML-Serialisierung bzw. -deserialisierung in einem Aufwasch speichern bzw. laden.

    Wenn man für die XML-Datei noch eine spezielle Endung verwendet (.game) könnte man diese auch als Endung registrieren.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    LaMiy schrieb:

    kann man doch auch händisch in Windows machen
    Unter der MFC (C++) war das standard, dass eine eigene Endung registriert wurde, einfach durch den Start des betreffenden Programms.
    Oder mit Kommandozeilenparameter -Register bzw. -Unregister.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    wie man eine eigene Dateiendung überhaupt benutzt

    Das kannst nur du allein wissen, denn du bist der einzige, der die Objektstruktur des Programmes kennt und somit weiß, was gespeichert und geladen werden muss. Wie du das genau machst bleibt dir überlassen, du kannst es in irgend ner Scripsprache (XML und dergleichen) machen, du kannst selber so eine Sprache erfinden, du kannst es aber auch rein Binär speichern, usw. Den Speicher- und Ladealgorithmus musst du aber selber schreiben.

    phil schrieb:

    wie geht das?

    msdn.microsoft.com/de-de/libra…lserializer(v=vs.80).aspx
    Beispiel für Serialisierung:

    VB.NET-Quellcode

    1. Dim writer As New StreamWriter("c:\MyObject.xml")
    2. Dim serializer As New XmlSerializer(MyObject.GetType)
    3. serializer.Serialize(writer, MyObject)
    4. writer.Close()
    Deserialisierung:

    VB.NET-Quellcode

    1. Dim reader As New StreamReader("c:\MyObject.xml")
    2. Dim deserializer As New XmlSerializer(MyObject.GetType)
    3. MyObject = CType(deserializer.Deserialize(reader), MyStructure)
    4. reader.Close()
    Das Object ist definiert als Dim MyObject = New MyStructure.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „petaod“ ()

    Entschuldigung wegen meiner langen Abwesenheit, habe heute viel zu tun
    Also...

    ich habe mal nach serialisation "gegoogelt"
    dank dieses PDF's weiß ich jetzt, was das ist. 8o
    Ich glaube, das ist genau das, was ich möchte! :thumbsup:
    mir kommt es gar nicht auf die Dateiendung an oder dass man durch klicken auf die Datei sofort zum Programm kommt.

    Allerdings verstehe ich das nicht so ganz:

    petaod schrieb:

    Das Object ist definiert als Dim MyObject = New MyStructure.

    ich möchte doch mein "world" serialisieren und nicht irgendein MyStructure - was ist das überhaupt?
    Bestimmt ist das eine richtig bescheuerte Frage, aber ich bin ein absoluter Anfänger. ;(
    Den Quellcode habe ich ausprobiert und genau an der Stelle .getType ist ein Fehler aufgetreten
    @timmi31061

    genau das habe ich gemacht: (erstmal das Speichern)

    VB.NET-Quellcode

    1. Dim writer As New StreamWriter(".\saves\world.xml") 'mache es eigentlich mit einem SaveFileDialog
    2. Dim serializer As New XmlSerializer(world.GetType)
    3. serializer.Serialize(writer, world)
    4. writer.Close()

    An der Stelle .GetType ist dann der Fehler: "Fehler beim Reflektieren des Typs 'WindowsApplication1.World'." aufgetreten.
    Da ist mir dann das hier aufgefallen:

    petaod schrieb:

    Das Object ist definiert als Dim MyObject = New MyStructure.

    --> irgendwelche Ideen?
    Mein world ist eine ganz normale -Serializable- Klasse mit einem parameterlosem Konstruktor.
    In ihr befinden sich weitere eigens erstellte Objekte, ein paar public Variablen, ein Dictionary und natürlich ein paar Methoden.

    EDIT:
    Entschuldigung, ich meinte natürlich Sub's und Funktionen, Methoden sind aus Java ;)

    phil schrieb:

    Was heißt raten?
    Ich weiß nicht wie dein Code aussieht.
    Andererseits habe ich eigentlich auch keine Lust, deinen Code zu debuggen.

    Du hast alle Informationen, die du benötigst.
    Ein bisschen Engineering darfst du selbst auch noch leisten.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    phil schrieb:

    An der Stelle .GetType ist dann der Fehler: "Fehler beim Reflektieren des Typs 'WindowsApplication1.World'." aufgetreten.
    Scheinbar ist deine world für die Serialisierung nicht geeignet.

    Fang mit einer ganz einfachen Klasse an, nur testweise sie zu serialisieren / deserialisieren.
    Dann kannstese immer komplexer machen, oder sonstwie herumprobieren, warum die einfache Klasse geht, die World aber nicht.

    Ein Serialisierungs-Hindernis sind zB. Events.