Serialisierung: Unterschied zwischen den Versionen

Aus Das Sopra Wiki
Jan (Diskussion | Beiträge)
Keine Bearbeitungszusammenfassung
LeonH (Diskussion | Beiträge)
Keine Bearbeitungszusammenfassung
 
(14 dazwischenliegende Versionen von 5 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
{{review}}
{{review}}
{{löschen}}
{{Navi:Implementierung}}
{{Navi:Implementierung}}
Serialisierung<ref name="RunTimeRerial">http://msdn.microsoft.com/en-us/magazine/cc301761.aspx Jeffrey Richter: Run-time Serialization</ref> bezeichnet den Vorgang, ein [[Objekt]] in einen Datenstrom umzuwandeln. Dieser kann dann dann als auf einer Festplatte gespeichert oder über ein Netzwerk übertragen werden. C# stellt dafür Klassen bereit.
Serialisierung<ref name="RunTimeRerial">http://msdn.microsoft.com/en-us/magazine/cc301761.aspx Jeffrey Richter: Run-time Serialization</ref> bezeichnet den Vorgang, ein [https://docs.microsoft.com/de-de/dotnet/api/system.object?view=netcore-3.1 Objekt] in einen Datenstrom umzuwandeln. Dieser kann dann als auf einer Festplatte gespeichert oder über ein Netzwerk übertragen werden. C# stellt dafür Klassen bereit.


== Formate ==
== Formate ==
Zeile 13: Zeile 14:


== Was kann Serialisiert werden ==
== Was kann Serialisiert werden ==
Um Ein Objekt zu serialisieren braucht es extrem wenig Code. Man sollte allerdings beachten, daß nur sinnvolle Daten serialisiert werden. Instanzen der Klasse <tt>File</tt> können zum Beispiel nicht serialisiert werden. Der Grund ist, dass deren Inhalte nicht im Hauptspeicher liegen. Ebenfalls können einige XNA-Klassen nicht serialisiert werden, z.B. die <tt>Model</tt>-Klasse, weil Teile davon im Grafikkartenspeicher oder anderen Orten liegen. Wenn man nicht sicher ist, kann man sich mit F12 (oder Rechtsklick -> Go to Defninition) zum Code wechseln(oder zu den Metadaten). Und an den [[Attributen]] erkennen, ob sie serialisierbar sind und welche Felder ausgeschlossen werden.
Um Ein Objekt zu serialisieren braucht es extrem wenig Code. Man sollte allerdings beachten, daß nur sinnvolle Daten serialisiert werden. Instanzen der Klasse <tt>File</tt> können zum Beispiel nicht serialisiert werden. Der Grund ist, dass deren Inhalte nicht im Hauptspeicher liegen. Ebenfalls können einige XNA-Klassen nicht serialisiert werden, z.B. die <tt>Model</tt>-Klasse, weil Teile davon im Grafikkartenspeicher oder anderen Orten liegen. Wenn man nicht sicher ist, kann man sich mit F12 (oder Rechtsklick -> Go to Defninition) zum Code wechseln(oder zu den Metadaten). Und an den [[Serialisierung#Attribute|Attributen]] erkennen, ob sie serialisierbar sind und welche Felder ausgeschlossen werden.
Der XmlSerializer hat weitere Einschränkungen:
Der XmlSerializer hat weitere Einschränkungen:
* Eine Klasse die Xml-serialisiert werden soll, braucht einen parameterlosen Konstrukor.
* Eine Klasse die Xml-serialisiert werden soll, braucht einen parameterlosen Konstrukor.
* keine Zweidimensionale Arrays
* keine Zweidimensionale Arrays
* (Die Klasse <tt>Dictionary</tt> und einige andere Klassen, von denen man eigentlich denkt, dass sie gehen müssten, sind nicht erlaubt)
* (Die Klasse <tt>Dictionary</tt> und einige andere Klassen, von denen man es eigentlich nicht denkt, sind nicht erlaubt)
 


== Attribute ==
== Attribute ==
Zeile 45: Zeile 45:
public class UnitAi
public class UnitAi
{
{
   pubilc StateMachineState state;
   public StateMachineState state;
   private int abc;
   private int abc;
}
}
</source>
</source>
Wenn eine Instanz dieser Klasse binär serialisiert und gespeichert wird, werden folgende Daten gespeichert:
Wenn eine Instanz dieser Klasse serialisiert und gespeichert wird, werden folgende Daten gespeichert:
* BinaryFormatter
* Beim BinaryFormatter
** der Integer <tt>hitPoints</tt>
** Der Integer <tt>hitPoints</tt>
** das Strukt <tt>position</tt> mit seinen Feldern
** Das Strukt <tt>position</tt> mit seinen Feldern
** die Referenz <tt>unitAi</tt> und die Instanz auf die sie zeigt. Und entsprechend dann auch deren Felder <tt>state</tt> und <tt>abc</tt>.
** Die Referenz <tt>unitAi</tt> und die Instanz auf die sie zeigt. Und entsprechend dann auch deren Felder <tt>state</tt> und <tt>abc</tt>.
* XmlSerializer
* Beim XmlSerializer
** der Integer <tt>hitPoints</tt>
** Der Integer <tt>hitPoints</tt>
** das Strukt <tt>position</tt> mit seinen Feldern
** Das Strukt <tt>position</tt> mit seinen Feldern
Die Referenz <tt>unitAi</tt> wird nicht serialisiert, da sie als private deklariert ist
** Die Referenz <tt>unitAi</tt> wird nicht serialisiert, da sie als private deklariert ist [[Kategorie:Code-Beispiele]]
 


== Referenzen ==
== Referenzen ==
Zeile 73: Zeile 72:
void SaveUnit(GameUnit gameUnit, String path)
void SaveUnit(GameUnit gameUnit, String path)
{
{
FileStream fs = null;
  FileStream fs = null;
try
  try
{
  {
  fs = new FileStream(path, System.IO.FileMode.Create);
    fs = new FileStream(path, System.IO.FileMode.Create);
  BinaryFormatter bf = new BinaryFormatter();
    BinaryFormatter bf = new BinaryFormatter();
  bf.Serialize(fs, gameUnit);
    bf.Serialize(fs, gameUnit);
}
  }
catch (Exception e)
  catch (Exception e)
{
  {
  // TODO: Fehlerbehandlung hier
    // TODO: Fehlerbehandlung hier
}
  }
finally
  finally
{
  {
  // Immer den Stream schliessen
    // Immer den Stream schliessen
  if (fs != null)
    if (fs != null)
     {
     {
       fs.Close();
       fs.Close();
     }
     }
   }
   }
}
}
}
</source>
</source>
Zeile 100: Zeile 98:
GameUnit LoadUnit(String path)
GameUnit LoadUnit(String path)
{
{
FileStream fs = null;
  FileStream fs = null;
try
  try
{
  {
  fs = new FileStream(path, FileMode.Open);
    fs = new FileStream(path, FileMode.Open);
  BinaryFormatter bf = new BinaryFormatter();
    BinaryFormatter bf = new BinaryFormatter();
               
                 
  return (GameUnit)bf.Deserialize(fs);  
    return (GameUnit)bf.Deserialize(fs);  
}
  }
catch (Exception e)
  catch (Exception e)
{
  {
  // TODO: Fehlerbehandlung hier
    // TODO: Fehlerbehandlung hier
  return null;
    return null;
}
  }
finally
  finally
{
  if (fs != null)
   {
   {
     fs.Close();
     if (fs != null)
    {
      fs.Close();
    }
   }
   }
}
}
}
</source>
</source>
Zeile 133: Zeile 131:
void SaveUnit(GameUnit gameUnit, String path)
void SaveUnit(GameUnit gameUnit, String path)
{
{
FileStream fs = null;
  FileStream fs = null;
try
  try
{
  {
  fs = new FileStream(path, System.IO.FileMode.Create);
    fs = new FileStream(path, System.IO.FileMode.Create);
  XmlSerializer seri = new XmlSerializer(typeof(GameUnit));
    XmlSerializer seri = new XmlSerializer(typeof(GameUnit));
  seri.Serialize(fs, gameUnit);
    seri.Serialize(fs, gameUnit);
}
  }
catch (Exception e)
  catch (Exception e)
{
  {
  // TODO: Fehlerbehandlung hier
    // TODO: Fehlerbehandlung hier
}
  }
finally
  finally
{
  {
  // Immer den Stream schliessen
    // Immer den Stream schliessen
  if (fs != null)
    if (fs != null)
     {
     {
       fs.Close();
       fs.Close();
     }
     }
   }
   }
}
}
}
</source>
</source>
Zeile 159: Zeile 156:
GameUnit LoadUnit(String path)
GameUnit LoadUnit(String path)
{
{
FileStream fs = null;
  FileStream fs = null;
try
  try
{
  {
  fs = new FileStream(path, FileMode.Open);
    fs = new FileStream(path, FileMode.Open);
  XmlSerializer seri = new XmlSerializer(typeof(GameUnit));                 
    XmlSerializer seri = new XmlSerializer(typeof(GameUnit));                 
  return (GameUnit)seri.Deserialize(fs);  
    return (GameUnit)seri.Deserialize(fs);  
}
  }
catch (Exception e)
  catch (Exception e)
{
  {
  // TODO: Fehlerbehandlung hier
    // TODO: Fehlerbehandlung hier
  return null;
    return null;
}
  }
finally
  finally
{
  if (fs != null)
   {
   {
     fs.Close();
     if (fs != null)
    {
      fs.Close();
    }
   }
   }
}
}
}
</source>
</source>
Zeile 188: Zeile 185:
Man kann mit Serialisierung auch Daten über ein Netzwerk schicken. Das Prinzip ist das gleiche, da die Formatter auf Streams arbeiten. Was für einen Stream man nimmt ist ihnen egal. Für Netzwerkfunktionalität bieten sich entweder die speziellen [[XNA]]-Klassen dafür an, oder man schreibt die Funktionalität selbst. Dies ist flexibler und man braucht keinen [[XBox 360|XBox-Live]]-Account. Dafür funktioniert sie auf der XBox nicht.
Man kann mit Serialisierung auch Daten über ein Netzwerk schicken. Das Prinzip ist das gleiche, da die Formatter auf Streams arbeiten. Was für einen Stream man nimmt ist ihnen egal. Für Netzwerkfunktionalität bieten sich entweder die speziellen [[XNA]]-Klassen dafür an, oder man schreibt die Funktionalität selbst. Dies ist flexibler und man braucht keinen [[XBox 360|XBox-Live]]-Account. Dafür funktioniert sie auf der XBox nicht.


Die nötigen Klassen finden sich im [[Namespace]]
Die nötigen Klassen finden sich im [[Namensraum]]
  System.Net.Sockets
  System.Net.Sockets


Zeile 222: Zeile 219:
* Leistungsfähiger als die beiden oben ist der SoapFormatter
* Leistungsfähiger als die beiden oben ist der SoapFormatter


== Video Tutorial ==
{{BA|Vogty|hier befand sich noch ein Abschnitt "Video Tutorial" bestehend aus einer Verlinkung auf ein MSDN Video, dieses existiert aber nicht mehr, ich habe den Abschnitt entfernt}}
Auf MSDN gibt es auch einen Webcast zum Thema<ref name="SerWebcast">http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?EventID=1032292924&EventCategory=3&culture=en-US&CountryCode=US MSDN Webcast: Advanced Serialization (Level 300)</ref><noinclude>


== Referenzen ==
== Referenzen ==