Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Object - Collection - Binary File: Using serialization and deserialization to work with binary files based on collections

0.00/5 (No votes)
20 Nov 2008 1  
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.

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:

  1. A class we can instantiate our objects from.
  2. Some sort of collection to push these objects in – which is a hashtable in our case.
  3. A a binary writer to actually save our data package to disk.
  4. 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.

  1. The Data Class: First of all, we add a new class called “cItem” [1] and give it a property.
  2. 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.

  3. The Collection: To fulfill the second requisite, we switch back to our “BinaryWriter” Module and add some Imports statements. In detail, that is:
  4. 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()
        '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 cItem
        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("Value" & iCounter, oItem)
            'destroy our Item
            oItem = Nothing
        Next
    End Sub
  5. 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.
  6. 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
  7. 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.
  8. Private Sub Deserialize()
        Dim oItemCollection As Hashtable
        Dim oFileReader As FileStream
        Dim oFormatter As BinaryFormatter
    
        'Define our Collection. Corresponting 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 file, so we initialize
        'a Filestream
        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 ;)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here