Binary File (1/2)

Binary File (1/2). Datenspeicherung per Serialisation.

Dann und wann kommt man an den Punkt an dem man eine .Net-Applikation entwickelt, die Daten speichern muss. In den meisten Fällen wird man in Richtung Datenbanken gehen um Daten (relational) zu halten, in manchen Fällen jedoch ist entweder keine Datenbank nötig oder eine Datenbank steht nicht zur Verfügung.

Der populärste Weg eine Anwendung zu entwickeln die mit strukturierten Daten hantiert aber keine klassische Datenbank wie MSSQL nutzt, wäre mit XML zu arbeiten. Grundsätzlich verrichtet XML eine großartige Arbeit und wenn man ein wenig mit XML vertraut ist, kann man in .Net mit einem starken Funktionsportfolio schnell und effektiv arbeiten.

Aber da ist noch mehr.

In diesem Artikel werde ich einen näheren Blick auf eine Technologie werfen, die es erlaubt einfach und unkompliziert Objekte mit Hilfe von Serialisation zu speichern. Zudem ist der Zugriff und die Arbeit mit dieser Technologie durchaus vergleichbar mit dem Arbeiten auf einer einfachen Datenbank. Grund genug sich damit näher zu beschäftigen.

Wir brauchen erstmal nur drei Zutaten für unser System:

  1. Eine Klasse aus der wir Objekte instanzieren können (um sie später zu speichern)
  2. Eine Art von Collection in die Objekte gepusht werden können (in unserem Fall eine Hashtable)
  3. Ein Binary Writer um unsere Daten tatsächlich auf die Platte zu speichern.

Da die Theorie hier verwirrender klingt als es eigentlich ist, ein komplettes Beispiel.

Vorbereitung. In VS2005 erstellen wir eine neue Command Line Application in VB.net. Das initiale “Module1″-Modul benennen wir in “Binarywriter” um und speichern das Projekt an einem geeigneten Ort. Nachdem das geschehen ist, können nun die einzelnen Komponenten hinzugefügt werden die wir oben mit den drei Zutaten definiert haben

1. Die Klasse. Als erstes fügen wir eine neue Klasse hinzu die “cItem” [1] heißt und geben dieser eine Property.

Public Class cItem

    Private _dValue As Double


    Public Property Value()
        Get
            Return _ dValue
        End Get
        Set(ByVal Value)
            _ dValue = (Value * 1000)
        End Set
    End Property
End Class

Aus diese Klasse rekrutieren sich die späteren Objekte die wir mit Hilfe einer Collection als binäre Datei speichern wollen.

2. Die Collection. Gehen wir zurück zu unserem “BinaryWriter”-Modul und fügen, um die zweite Zutat nutzen zu können, ein paar Import-Statements ein:

Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Runtime.Serialization

Hiernach kommen wir zur eigentlichen Erstellung der Collection und der Befüllung der neuen Collection durch eine größere Anzahl von randomisierten Werten. Die Einzelwerte werden jeweils durch Objekt-Instanzen der cItem-Klasse gebildet.

Private Sub Serialize()
    'define our Collection – a hashtable in our case
    'because it will hold all the Items we are going to
    'create, we will call it ItemCollection
    Dim oItemCollection As New Hashtable
    Dim oItem As Object
    Dim iCounter As Integer

    'We will fill our Data-File with a mass of values
    For iCounter = 1 To 10000
        'Make new Item from cItems
        oItem = New cItem
        Randomize()
        'Give it a random Value
        oItem.Value = Rnd()
        'Add it to our collection
        oItemCollection.Add(“Key” & iCounter , oItem)
        'destroy our Item
        oItem = Nothing
    Next
End Sub
3. Der Binary Writer. Nun können wir die Daten in unserer gefüllten Collection als binäre Datei speichern. Hierzu benötigen wir einen FileStream und einen BinaryFormatter um die Collection in eine angegebene Datei zu streamen.
Private Sub Serialize()
    (...)

    'As we want to write a binary file, we need to open a
    'FileStream to create one. That’s why we need the System.IO
    'Import for, btw.
    Dim oFileWriter As New FileStream(“DataFile.dat “, FileMode.Create)
    'Construct a BinaryFormatter and use it to serialize the data
    'to the stream. 
    Dim oFormatter As New BinaryFormatter
    Try
        oFormatter.Serialize(oFileWriter, oItemCollection)
    Catch e As SerializationException
        Console.WriteLine(“Serialization failed. Reason: “ & e.Message)
        Throw
    Finally
        oFileWriter.Close()
    End Try
End Sub

Ergebnis. Damit haben wir auch schon gezeigt was ich in diesem Artikel vorstellen wollte. Nämlich dass man sehr einfach Daten in eine binäre Datei schreiben kann.  Die Alternative, Objekte in einer Collection zu halten, um sie zu serialisieren, hat in manchen Anwendungsgebieten durchaus Vorteile. Es muss halt nicht immer “die große Datenbank” sein.

Da man als Collection grundsätzlich alle Typen von Collections nutzen kann, kann man hier mit einer sinnvollen Auswahl und einem sinnvollen Design der Daten-Klasse viele Vorteile nutzen um sauberen und effizienten Code zu erhalten und damit eine robuste Anwendung. Eine Hashtable habe ich hier exemplarisch eingesetzt und bietet sich eigentlich hauptsächlich bei alphabetischen Keys an.

Anmerkung. Das oben gezeigte funktioniert leider nicht beim .Net Compact Framework.


[1] Ich weiss das Manche nun sagen werden, dass “cItem” nicht der gängigen Namenskonvention in .Net entspricht. Das mag auch für andere Dinge in meinem Code gelten. Dem möchte ich auch nicht widersprechen, aber was ich hier tue ist, die Namenskonventionen meines Unternehmens zu benutzen. Und das nicht nur, weil ich sie entwickelt habe ;)