Introduction
The most popular way to build applications that deal with structured data but do not use a classical database like a SQL Server is to work with XML. Basically, XML does a fantastic job, and if you 're familiar with XML in .NET, you can work with a powerful set of functions to deal with your stored data.
But there is more.
Using the code
In this tutorial, we will take a closer look at a technology that allows you to store objects externally with ease, retrieve them effortlessly, and work with them as if you were dealing with some kind of simple database.
We only do need four ingredients to build up our system:
- A class we can instantiate our objects from.
- Some sort of collection to push these objects in – which is a hashtable in our case.
- A a binary writer to actually save our data package to disk.
- A binary reader to retrieve our data back.
This actually might sound more confusing than it is, so we better jump right into it and take a look at a basic example.
Let's fire up VS 2005 and start a new command line application in VB.NET. Rename the initial module from “Module1
” to “Binarywriter
” and save the project to a suitable location. We can now start to look closer at our subject.
- The Data Class: First of all, we add a new class called “
cItem
” [1] and give it a 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
Later we are going to derive objects from this class and store them in our collection to save them right away into a binary file.
- The Collection: To fulfill the second requisite, we switch back to our “
BinaryWriter
” Module and add some Imports
statements. In detail, that is:
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Runtime.Serialization
After that, we’re adding a Sub called “Serialize
” in which we’re going to fill up our collection with a larger amount of randomized values. The single values are stored in object instances of our cItem
class.
Private Sub Serialize()
Dim oItemCollection As New Hashtable
Dim oItem As cItem
Dim iCounter As Integer
For iCounter = 1 To 10000
oItem = New cItem
Randomize()
oItem.Value = Rnd()
oItemCollection.Add("Value" & iCounter, oItem)
oItem = Nothing
Next
End Sub
- The Binary Writer: We are now ready to store our filled collection as a binary file. Therefore, we use a
FileStream
and a BinaryFormatter
to stream the collection to disk.
Private Sub Serialize()
Dim oFileWriter As New FileStream("DataFile.dat", FileMode.Create)
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
- The Binary Reader: To retrieve back our data from the data file, we make use of deserialization. Therefore, we add a new function to the
BinaryFile
Module and name it “Deserialize
”. To hold up the retrieved data, we initiate an empty hashtable. After that, we are going the same way back as we went to store the collection to the binary file and make use of a FileStream
, in addition with a BinaryFormatter
to actually access the data. After we cast the deserialized content of the data file, we are finished.
Private Sub Deserialize()
Dim oItemCollection As Hashtable
Dim oFileReader As FileStream
Dim oFormatter As BinaryFormatter
oItemCollection = New Hashtable
oItemCollection = Nothing
oFileReader = New FileStream("DataFile.dat", FileMode.Open)
Try
oFormatter = New BinaryFormatter
oItemCollection = _
DirectCast(oFormatter.Deserialize(oFileReader), Hashtable)
Catch e As SerializationException
Console.WriteLine("Deserialize failed. Reason: " & e.Message)
Throw
Finally
oFileReader.Close()
End Try
End Sub
We now have our data retrieved back in a hashtable.
Next steps: It is said in the introduction that it would be possible to work with binary files as if you are working with some kind of simple database. This is a true statement with no doubt, but slightly incorrect verbalization because – as you might already have noticed – we are not working with the data file itself, but execute operations against the collection which resides in memory.
This again is a great advantage because you can optimize your collection to your special needs.
But, let's look at two basic examples of how to work with our above designed system and access some data.
Access Values
In this case, you make use of the DictionaryEntry
and DirectCast
the entry to the cItem
class in order to access the actual value of the object.
Dim oEntry As DictionaryEntry
Dim iCounter As Integer = 0
Dim iValue As Integer
For Each oEntry In oItemCollection
iValue = DirectCast(oEntry.Value, cItem).Value
If iValue = iRandomNumber Then
iCounter += 1
End If
Next
Console.WriteLine("The value {0} was found {1} times", _
iRandomNumber, iCounter)
Result: This tutorial demonstrates how to easily store and retrieve data to/from binary files using a collection-derivate and (de-)serialization.
To hold objects in a collection and serialize them offers some advantages in contrast to classical databases in case the amount of data is not growing too big. Among these advantages is the fact that the data-file is stored as binary, which obviously results in a restrictive access to the data-file. Also, it enables fast and handy working with structured data because we are loading the complete data to memory, so every operation against the data is an operation in memory.
Also, it was shown how easily the retrieval of binary data files could be.
With a wisely selected collection type and a properly designed data-class, you can make use of a lot of advantages to write simple, efficient, and clean code which possibly results in a robust application. A hashtable as a collection was only used for demonstration purposes. Basically, you can use any type of collection (even your own). Together, with the data-class, you have plenty of tools to make your application deal properly with a binary file.
Remarks: Unfortunately, the method above does not apply for the .NET Compact Framework, so you cannot use this method to store data in a mobile device.
[1] I know many people would say that “cItem
” does not follow the usual naming convention in .NET. I won’t veto on that, but what I am doing here is following the naming conventions of my company. And that's not only because I was authoring it ;)