Objekte in Datei serialisieren

16/05/2009 - 18:40 von Alfred Sauerland | Report spam
Hallo zusammen,

ich habe eine Art Spiel erstellt und nun ist natürlich die Möglichkeit einer
"Spielstandsspeicherung" eine interessante Sache, um nach einer
Unterbrechung genau da weiter machen zu können, wo man davor war. Es gibt
natürlich jede Menge Objekte die das Spielgeschehen verwalten und
repràsentieren. Daher bin ich auf die Serialisation gekommen. Ich habe auch
ein wenig damit gespielt und klappt soweit auch. Nur frage ich mich, wie das
geht mehrere Objekte in einer Datei zu speichern. Denn es gibt:

a) Genersische Listen von Objekten... kann ich da die ganze Liste als solche
serialisieren oder muß ich das für jedes einzelne Objekt daraus machen?
b) Viele verschiede eigene Klassen mit Objekten

So mache ich das:

Public Function Serialize() As Boolean
If Not Me.Object.GetType.IsSerializable Then
Throw New Xml.XmlException("Value 'Object' must be
serializable.")
End If
Try
Using StreamWriter As New System.IO.StreamWriter(Me.TargetFile)
Dim XmlSerializer As New
System.Xml.Serialization.XmlSerializer(Me.Object.GetType)
XmlSerializer.Serialize(StreamWriter, Me.Object)
End Using
Return True
Catch ex As Exception
Return False
End Try
End Function

Public Function Deserialize() As Object
If Not Me.Object.GetType.IsSerializable Then
Throw New Xml.XmlException("Value 'Object' must be
serializable.")
ElseIf Not My.Computer.FileSystem.FileExists(Me.TargetFile) Then
Throw New IO.FileNotFoundException("Value 'TargetFile' must be a
file that exists.")
End If
Try
Using StreamReader As New System.IO.StreamReader(Me.TargetFile)
Dim XmlSerializer As New
Xml.Serialization.XmlSerializer(Me.Object.GetType)
Return XmlSerializer.Deserialize(StreamReader)
End Using
Catch ex As Exception
Return Nothing
End Try
End Function

Ich stell mir die Schwierigkeit da vor, weil das Programm dann ja
durcheinander kommt was zu welchem Objekt gehört.

Gibt es vielleicht eine schön gepflegte Wrapper-Klasse für die
Serialisation? Über Google findet man zwar was, aber scheint nicht so das
wahre dabei zu sein.

Könnt ihr mir da weiterhelfen?

Grüße!
 

Lesen sie die antworten

#1 Karsten Sosna
17/05/2009 - 08:27 | Warnen spam
Hallo Alfred,
Nur frage ich mich, wie das geht mehrere Objekte in einer Datei zu
speichern.



Das geht nur über 1 Objekt. Du muss also ein Objekt erstellen, welches alle
anderen Objekte beinhaltet.

a) Genersische Listen von Objekten... kann ich da die ganze Liste als
solche serialisieren


Nicht alle Objekte lassen sich via XML serialisieren, dazu gehören IMHO auch
einige generische Listen.

oder muß ich das für jedes einzelne Objekt daraus machen?



Das ist Dir überlassen. Du kannst jedes Objekt einzeln serialisieren, was
zur Folge hat, das Du genauso Dateien wie Objekte hast. Ich persönlich würde
davon aber abraten. Wenn Objekte voneinander abhàngig und eines sich nicht
deserialsren làsst(Datei fehlt oder ist defekt) funktioniert das
Objektmodell nicht mehr. Sinnvoll wàre so etwas

Spielstànde
Spielstand_1
Spielstand_2
...
Spielstand_n

"Spielstànde" ist das Objekt welches serialisiert wird, wobei "Spielstànde"
auch eine Auflistung sein könnte(Hierzu beachte aber obige Anmerkung zur
XML-Serialisierung)

b) Viele verschiede eigene Klassen mit Objekten
Ich stell mir die Schwierigkeit da vor, weil das Programm dann ja
durcheinander kommt was zu welchem Objekt gehört.



Wenn Du eine "Spielstand"-Klasse erzeugst, sollte diese Klasse alle
Informationen beinhalten, die genau für dieses Spiel nötig sind um es
fortzusetzen. Hier mal ein einfaches Beispiel:
\\\
Private Scores As New List(Of Score)

Private Sub FRM_Form1_FormClosing(ByVal sender As Object, ByVal e As
System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Dim SW = IO.File.OpenWrite("C:\Temp\ScoreList.xml")
Dim formatter As New
System.Xml.Serialization.XmlSerializer(GetType(List(Of Score)))
formatter.Serialize(SW, Scores)
SW.Close()
End Sub

Private Sub FRM_Form1_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
If IO.File.Exists("C:\Temp\ScoreList.xml") Then
Dim SR = IO.File.OpenRead("C:\Temp\ScoreList.xml")
Dim formatter As New
System.Xml.Serialization.XmlSerializer(GetType(List(Of Score)))
Scores = DirectCast(formatter.Deserialize(SR), List(Of Score))
SR.Close()
For Each Score In Scores
Console.WriteLine(Score.Name)
Next
Else
InitScoreList()
End If
End Sub

Private Sub InitScoreList()
For n = 1 To 10
Dim score As New Score
score.Name = "NewPlayer" & Format(n, "00")
Scores.Add(score)
Next
End Sub
'
<Serializable()> _
Public Class Score
Public Name As String = ""
Public LastDate As Date = Now
Public Money As Decimal = 0
Public Health As Double = 100
Public Power As Double = 75
Public Level As Integer=1
Public Weapons As New List(Of Weapon)
End Class

Public Class Weapon
Public Name As String
Public Strength As Double
Public Magazines As New List(Of Magazine)
End Class

Public Class Magazin
Public Ammo As String
Public Count as Integer
Public Strength As Double
End Class
///

Wie Du siehst làsst sich die List(Of T) serialisieren, die kannst Du also
nehmen. Ein Spielstand gehört ja immer zu einem Spieler. Ein Spieler kann
aber auch mehrere Dinge besitzen. Ich hab das hier mal mit Waffen gemacht.
Die Weapons-Auflistung beinhaltet dann alle Waffen die dieser Spieler
besitzt. So musst Du das mit allen anderen Dingen auch machen., alles was
zusammen gehört gehört in eine Auflistung. Diese untergeordneten Klassen
können wiederum zusàtzliche Auflistungen haben(Hier die Magazine). So
bekommst Du ein vernünfiges Objektmodell, das Du nicht nur einfach speichern
und laden kannst, sondern es erleichtert Dir auch den spàteren Umgang. Die
Klassen können ja noch zusàtzliche Member haben, bspw. eine Load-Methode die
eine neues Magazin in die Waffe einführt oder eine Fire-Methode, die dann
automatisch die Anzahl der Patronen im aktuellen Magazin dekrementiert. Hier
sind wirklich keine Grenzen gesetzt.
Gruß Scotty

Ähnliche fragen