Dienstag, 1. Juni 2010

Objekte serialisieren

Serialisierung stellt ein effizientes Konzept zur Konvertierung von Objekten und anschließender Speicherung dieser dar.
Bei vielen Programmen sollen die eingegebenen Daten nicht nur einmalig beim Ausführen verwendet werden, sondern auch bei der nächsten Ausführung des Programms zur Verfügung stehen.
Folglich müssen die Daten gespeichert werden. Mittels Streams lassen sich Daten in Dateien bzw. in den Speicher schreiben. StreamWriter und StreamReader sind sicherlich die bekanntesten Vertreter, sie eignen sich besonders gut Textdateien.

Daten im Textformat abzuspeichern, ist in den meisten Fällen jedoch aufwendig, unsicher und nicht gerade elegant.
Angenommen, wir hätten ein Programm zur Verwaltung von Bankdaten geschrieben, die Kunden wären sicher nicht erfreut über eine leserliche Textdatei im Format: Name - Kontonr - Kontostand.
Für größere Klassen würde die manuelle Konvertierung sicherlich auch ziemlich lästig sein.
In .Net gibt es zum Glück Klassen, die uns diese Arbeit abnehmen - Klassen können serialisiert werden, das heißt, sie werden in ein bestimmtes Format konvertiert und können dann in eine Datei geschrieben werden.
Grundsätzlich stehen die Klassen BinaryFormatter, SoapFormatter und XmlSerializer zur Verfügung.
Mittels XmlSerializer können Daten ins XML - Format serialisiert werden, mit SoapFormatter ins Soap - Format.
BinaryFormatter
serialisiert Objekte in ein binäres Format, für diese Klasse gibt's jetzt ein Beispiel:

Und zwar soll hier eine minimale Mitarbeiterverwaltung als Beispiel dienen:
Mitarbeiter werden als Instanzen der Klasse Employee gespeichert:
[Serializable]
public class Employee
{
static int GlobalID = 0;

int ID;
string Surname, Prename;
double Salary;
string Email;

public Employee(string surname, string prename)
{
ID = GlobalID++;
Surname = surname;
Prename = prename;
}
}
Das Attribut [Serializable] ist nötig, damit die Klasse serialisiert werden kann.
Für das einfache Beispiel geschieht die Serialisierung sowie die Deserialisierung beim Laden des Formulars:
private void Form1_Load(object sender, EventArgs e)
{
List DemoList = new List();
DemoList.Add(new Employee("Wurst", "Hans"));
DemoList.Add(new Employee("Mustermann", "Max"));

SerializeEmployees(DemoList);

List DeserializedList = DeserializeEmployees();
}
In dieser Funktion wird zuerst eine Liste vom Typ Employee angelegt und dieser "Hans Wurst" und "Max Mustermann" hinzugefügt.
Dann wird die von mir angelegt Funktion zum Serialisieren aufgerufen, welche so aussieht:
private void SerializeEmployees(List employees)
{
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = new FileStream(Application.StartupPath + "\\list.emp", FileMode.Create);
bf.Serialize(fs, employees);
fs.Close();
}
Die Klasse BinaryFormatter stellt die Funktion Serialize() zur Verfügung, die als Parameter einen Stream sowie das zu serialisierende Objekt erwartet.
In diesem Fall wird die Liste employees per FileStream in die Datei "list.emp" im Anwendungsverzeichnis geschrieben.

In Form1_Load() wird dann der Prozess umgekehrt und die Funktion zur Deserialisierung aufgerufen:
private List DeserializeEmployees()
{
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = new FileStream(Application.StartupPath + "\\list.emp", FileMode.Open);
List Result = (List)bf.Deserialize(fs);
fs.Close();
return Result;
}
BinaryFormatter stellt ebenfalls die Funktion Deserialize() zur Verfügung, aus dem übergebenen Stream wird ein Objekt erstellt. Dieses wird dann in den in Klammern vorgegebenen Typ (hier List) konvertiert und schließlich zurückgegeben.

Am Ende enthält die Liste DeserializedList in Form1_Load() die gleichen Mitarbeiter wie die ursprüngliche Liste.

Kommentare:

  1. Die Klasse Employee kann nicht deserialisiert werden, da sie einen Parameterlosen Konstruktor braucht ;)

    Gruß frisch.

    AntwortenLöschen
  2. In C# 2010 und mit .Net Framework 4.0 funktioniert der Code so, aber stimmt, ich glaube da war was in älteren .Net Versionen ;)

    AntwortenLöschen