vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Zippen wie die Profis!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik: Dateisystem · Dateien - allgemein   |   VB-Versionen: VB.NET07.01.08
Daten speichern durch Serialisierung (VB.NET)

Profitieren Sie vom Umstieg auf VB.NEt. Das Speichern von Daten war noch nie so einfach! Das Zauberwort lautet Serialisierung

Autor:   Maximilian OsenbergBewertung:     [ Jetzt bewerten ]Views:  37.207 
www.speedsoft-developing.deSystem:  WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11kein Beispielprojekt 

VB6-Programmierer, die auf VB.NET umsteigen, werden wohl zum Speichern von Daten, wie sie z.B. für E-Mail-Konten benötigt werden, gerne auf die alten VB6-Funktionen zurückgreifen. Bislang war das Speichern solcher Daten allerdings kompliziert. Klar, man hat ein Trennzeichen, wie z.B. vbTab zwischen die einzelnen Angaben gesetzt oder für jedes Datenfeld eine eigene Zeile verwendet, und das ganze in eine Textdatei geschrieben.

VB.NET eröffnet dem Programmierer hier aber durch die sog. Serialisierung ganz neue Möglichkeiten. Alle Klassen, Structures usw. müssen dabei die Option "Serialisierbar" aufweisen. Das Speichern in die Datei übernimmt das .NET Framework. Um den ganzen Vorgang noch mehr zu vereinfachen, werden wir im Folgenden eine Klasse mit generischen Funktionen erstellen - klingt kompliziert, ist aber einfach - durch die das Speichern einer kompletten Klasse zu einem Einzeiler wird.

Zunächst aber einmal die grundlegende Frage: "Was ist Serialisierung?" Nun, das bedeutet, dass der Zustand einer kompletten Klasse - also die Variablen - in eine einzige Datei gespeichert werden. Der Programmierer muss nur eine .NET-Funktion aufrufen, der die Instanz der zu speichernden Klasse übergeben wird. Schauen Sie sich einmal die folgende Klasse an. Sie verwendet bereits die vorhin schon angesprochene Serializer-Klasse.

Imports System.IO
 
<Serializable()> _
Public Class Kontoverwaltung
  Public Items As List(Of Account)
  Private Shared dataPath As String = _
    Path.Combine(Application.StartupPath, "accounts.dat")
 
  Public Sub New()  
    ' Erstellen einer neuen, leeren List(Of T)
    Items = New List(Of Account)
  End Sub
 
  Public Sub Save()
    ' Aufrufen der generischen Serialize-Funktion für 
    ' die Klasse Kontoverwaltung
    Serializer.Serialize(Of Kontoverwaltung)(dataPath, Me)
  End Sub
 
  Public Shared Function Load() As Kontoverwaltung
    ' Dadurch, dass die Klasse "Sub New()" aufweist, kann die 
    ' Serializer-Klasse, wenn keine Datei vorhanden ist, 
    ' eine DefaultInstance zurückgeben.
    Return Serializer.DeSerialize(Of Kontoverwaltung)(dataPath)
  End Function
 
  ' ...Weitere Funktionen der Klasse (werden hier nicht aufgeführt)
End Class
<Serializable()> _
Public Structure Account
  Dim Name As String
  ' Weitere Variablen deklarieren...
End Structure

Bevor wir uns der generischen Klasse widmen, betrachten wir zunächst einmal obigen Code. Wie Sie sehen, ist die Klasse als "Serializable" deklariert. Das heißt, sie kann vom System abgespeichert werden. Wichtig ist, dass auch die Structure Account "Serializable" ist. Bei den von .NET bereitgestellten Klassen brauchen Sie sich keine Sorgen machen, diese lassen sich alle serialisieren. Bei der Funktion Save wird die "Public Shared Function Serialize(Of T)" aufgerufen, dieser wird der Dateipfad und die zu speichernde Instanz der Klasse übergeben. Da die Klasse ja nur aus einer List(Of Account) besteht könnte man auch nur die Variable Items speichern. Da aber im Normalfall weitere Variablen hinzukommen, habe ich in diesem Beispiel darauf verzichtet. Die Funktion Load gibt eine Instanz der Kontoverwaltungsklasse zurück, die aus der Datei gelesen wird. Da die Klasse "Sub New()" (parameterlos) implementiert, kann die Serializer-Klasse, sofern die Datei nicht vorhanden ist, eine neue Instanz der Kontoverwaltung zurückgeben. Alternativ kann auch eine Standard-Instanz als Funktionsparameter übergeben werden.

Übrigens: Über den Parameter "<NonSerialized()>" vor einer Variablen können Sie diese von der Serialisierung ausschließen.

So, jetzt widmen wir uns aber einmal der Serializer-Klasse. Ich hoffe, der Begriff generisch ist Ihnen geläufig. Wenn nicht, bitte Googlen, da sonst der Rahmen dieses Tipps gesprengt würde.

Imports System.Runtime.Serialization.Formatters.Binary
Imports System.IO
Imports System.IO.Compression
 
Public Class Serializer
  Public Shared Sub Serialize(Of T)(ByVal compression As Boolean, _
    ByVal path As String, ByVal instance As T)
 
    Try
      Dim fs As Stream = New FileStream(path, FileMode.OpenOrCreate)
      Dim bf As New BinaryFormatter
      If compression Then fs = New GZipStream(fs, CompressionMode.Compress)
 
      bf.Serialize(fs, instance)
      fs.Close()
    Catch ex As Exception
      MessageBox.Show(ex.Message, Application.ProductName, _
        MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
  End Sub
 
  Public Shared Sub Serialize(Of T)(ByVal path As String, ByVal instance As T)
    Serialize(False, path, instance)
  End Sub
 
  Public Shared Function DeSerialize(Of T)(ByVal compression As Boolean, _
    ByVal path As String, ByVal defaultInstance As T) As T
 
    Try
      If Not File.Exists(path) Then 
        Return defaultInstance
      End If
      Dim fs As Stream = New FileStream(path, FileMode.OpenOrCreate)
      Dim bf As New BinaryFormatter
      If compression Then fs = New GZipStream(fs, CompressionMode.Decompress)
 
      DeSerialize = CType(bf.Deserialize(fs), T)
      fs.Close()
    Catch ex As Exception
      MessageBox.Show(ex.Message, Application.ProductName, _
        MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
  End Function
 
  Public Shared Function DeSerialize(Of T)(ByVal path As String, _
    ByVal defaultInstance As T) As T
 
    Return DeSerialize(Of T)(False, path, defaultInstance)
  End Function
 
  Public Shared Function DeSerialize(Of T As New)(ByVal path As String) As T
    Return DeSerialize(Of T)(path, New T)
  End Function
 
  Public Shared Function DeSerialize(Of T As New)( _
    ByVal compression As Boolean, ByVal path As String) As T
 
    Return DeSerialize(Of T)(compression, path, New T)
  End Function
End Class

Zunächst wird der Namespace, in dem sich der BinaryFormatter befindet, importiert. Für die Kompression ist zusätzlich noch der Io.Compression-Namespace und für den FileStream der Io-Namespace erforderlich. Wie Sie sehen, bietet der Code durch viele Überladungen und auch noch eine Funktion zum Komprimieren eine hohe Flexibilität. Nun aber zur Programmierung der "Sub Serialize". Zunächst wird ein Stream-Objekt erzeugt und in diesem eine neuen Instanz der FileStream Klasse gespeichert. Existiert die Datei nicht, so wird sie erstellt. Ist die Komprimierung aktiv, so wird in "Fs" ein neuer GZipSteam gespeichert. Den Rest erledigt der BinaryFormatter. Er schreibt den kompletten Inhalt der Klasse im binären Format in die Datei. Die "Sub DeSerialize" ist genau so, wie die "Sub Serialize" aufgebaut. Der Wesentliche Unterschied besteht im Zurückgeben einer Standard-Instanz, sofern die Datei nicht vorhanden ist und der Typenkonvertierung vom Rückgabewert des BinaryFormatters in den Typ T.

Das beste der Serialisierung: Sie können nachträglich Variablen hinzufügen oder löschen und das ohne die Datei, in die serialisiert wurde, zu löschen. So können Sie Updates an Kunden herausgeben, in denen Sich beispielsweise die "Structure Account" um wenige Variablen unterscheidet.

Am Schluss noch ein Hinweis: Wenn Sie vorhaben, größere Datenmengen, wie z.B. E-Mails mit den kompletten Anhängen zu serialisieren, empfehle ich persönlich das Verwenden einer eigenen Datei für jede E-Mail. Denn die Deserialisierten Daten werden im Arbeitsspeicher abgelegt und wollen wir doch nicht unnötig strapazieren
 

Dieser Tipp wurde bereits 37.207 mal aufgerufen.

Voriger Tipp   |   Zufälliger Tipp   |   Nächster Tipp

Über diesen Tipp im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Tipp, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Aktuelle Diskussion anzeigen (6 Beiträge)

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel