Binary File (2/2)

Binary File (2/2). Datenwiederherstellung.

Im ersten Teil dieses Beispiels habe ich gezeigt, wie man Objekte die aus einer Klasse instanziert wurden in einer Collection speichert um diese mittels BinaryFormatter in ein binäres File zu streamen. Im zweiten Teil möchte ich nun den umgekehrten Weg zeigen, nämlich wie man die Daten von der Platte wieder in die Anwendung bekommt.

Analog dem ersten Beispiel brauchen wir also einen Deserialisierer um die Daten aus unserem Binärfile zurückzulesen und zugreifbar zu machen. Um an den ersten Teil anzuknüpfen, führe ich die Nummerierung fort:

4. Deserialize. Wir fügen dem BinaryFile-Modul eine neue Funktion “Deserialize” hinzu. Hierin definieren wir zunächst eine leere Hashtable um den Inhalt der binären Datei aufzunehmen. Danach gehen wir analog der Serialisation den Weg über einen FileStream verbunden mit einem BinaryFormatter um auf die Wertedatei zuzugreifen. Wir casten den deserialisierten Inhalt der Datei als Hashtable und… fertig.

Private Sub Deserialize()
    Dim oItemCollection As Hashtable
    Dim oFileReader As FileStream
    Dim oFormatter As BinaryFormatter

    'Define our Collection. Corresponding to the Collection used
    'in the Serialize()-Function it’s a hashtable here.
    oItemCollection = new Hashtable
    oItemCollection = Nothing
    'We want to read from our binary data file, so we initialize
    'a Filestream
    oFileReader = New FileStream(“DataFile.dat”, FileMode.Open)

    Try
        oFormatter = New BinaryFormatter
        'Read entire file and direct cast it into our hashtable Collection
        oItemCollection = DirectCast(oFormatter.Deserialize(oFileReader), Hashtable)
    Catch e As SerializationException
        Console.WriteLine(“Deserialization failed. Reason: “ & e.Message)
        Throw
    Finally
        oFileReader.Close()
    End Try
End Sub

Unsere im ersten Teil eingetragenen Daten sind nun also über die Hastable wieder im Zugriff.

Weitere Schritte. In der EInleitung zum ersten Teil wurde postuliert, dass man auf der binären Datei arbeiten kann wie auf einer einfachen Datenbank. Das ist durchaus richtig aber nicht ganz korrekt formuliert, denn wie sich jetzt schon gezeigt hat, arbeiten wir ja nicht auf der Datei selber sondern führen alle weiteren Operationen auf der Collection aus. Hier also auf einer Hashtable.

Hashtables sind ein Kapitel für sich, dennoch möchte ich hier kurz auf zwei wesentliche Funktionalitäten eingehen um den Umgang mit Daten in diesem Beispiel zu komplettieren. Sicherlich ist der gezeigte Weg nicht unbedingt das Optimum, aber es zeigt, wie einfach auf unserer Datenmenge gearbeitet werden kann.

Zugriff auf bestimmte Keys. Der Zugriff auf Schlüsselwerte ist – wie erwartet – einfach. Hierzu muss nur die Collection auf einen Schlüsselwert abgefragt werden.

Dim iRandomNumber As Integer

Randomize()

'Get random number to check against the hashtable keys
iRandomNumber = CInt(Rnd() * 1000)       

If ItemCollection.ContainsKey(“Key” & iRandomNumber) Then
    Console.WriteLine(“The Key {0} was found in our Collection and has a Value of {1}”, iRandomNumber, ItemCollection.Item(“Key” & iRandomNumber).Value)
Else
    Console.WriteLine(“The value {0} was not found.”, iRandomNumber)
End If
Werte finden. Die von uns anfänglich randomisierten Werte sind ebenfalls einfach auffindbar. Im Worst-Case-Fall benötigen wir hier einen kompletten Durchlauf durch die Collection. Wenn man aber davon ausgeht, dass die Datenmengen eher moderat sein werden, weil sonst definitiv eine “große Datenbank” Sinn gemacht hätte, lässt sich dieses Manko mit der Performance wett machen.
'Let’s find some Item.Value
'Therefore we are make use of Dictionaries
Dim Entry As DictionaryEntry

'how often does this value exists in the entire Collection 
Dim iCounter As Integer = 0

'Current Value
Dim iValue As Integer

'Loop through the entire Collection
For Each Entry In ItemCollection
    'Extract Value from Collection-item
    iValue = DirectCast(Entry.Value, cItem).Value

    'If it is the Value we are looking for, then increment counter
    If iValue = iRandomNumber Then
        iCounter += 1
    End If
Next

Console.WriteLine(“The value {0} was found {1} times”, iRandomNumber, iCounter) 

Ergebnis. Ich habe gezeigt, dass auch die Deserialisation auf Binary Files einfach und schnell umgesetzt werden kann. Bezüglich dem Zugriff auf Werte oder Keys habe ich ebenfalls einfache Beispiele gezeigt. Hier konnte man sehen dass man im Worst-Case mit einem kompletten Collection-Durchlauf Zugriff auf alle Werte und Keys erhalten kann. Das ist Performance-Technisch wohl in der Regel auch nicht so kritisch.

Natürlich kann man bezüglich der Laufzeiten hier eine Menge tun. Angefangen von der sinnvollen Auswahl der Collection und das weise Design der Werte-Klasse bis hin zu Funktionalitäten und Operationen die direkt auf den Collections zur Verfügung stehen oder diese effektiv erweitern. Als Einstieg in Binary Files soll das hier aber erstmal genügen.