Êíèãà: C# 2008 Programmer
Binary Serialization
Binary Serialization
Consider the following class, BookMark
, which is used to stored information about web addresses and their descriptions:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace Serialization {
class Program {
static void Main(string[] args) {}
}
class BookMark {
private DateTime _dateCreated;
public BookMark() {
_dateCreated = DateTime.Now;
}
public DateTime GetDateCreated() {
return _dateCreated;
}
public string URL { get; set; }
public string Description { get; set; }
public BookMark NextURL { get; set; }
}
}
The BookMark
class contains properties as well as private variables. The NextURL
property links multiple BookMark
objects, much like a linked list. Let's now create two BookMark
objects and link them:
static void Main(string[] args) {
BookMark bm1, bm2;
bm1 = new BookMark {
URL = "http://www.amazon.com",
Description = "Amazon.com Web site"
};
bm2 = new BookMark() {
URL = "http://www.wrox.com",
Description = "Wrox.com Web site",
NextURL = null
};
//---link the first BookMark to the next---
bm1.NextURL = bm2;
}
You can serialize the objects into a binary stream by writing the Serialize() function:
static void Main(string[] args) {
//...
}
static MemoryStream Serialize(BookMark bookMark) {
MemoryStream ms = new MemoryStream();
FileStream fs = new FileStream(
@"C:Bookmarks.dat", FileMode.Create, FileAccess.Write);
BinaryFormatter formatter = new BinaryFormatter();
//---serialize to memory stream---
formatter.Serialize(ms, bookMark);
ms.Position = 0;
//---serialize to file stream---
formatter.Serialize(fs, bookMark);
return ms;
}
For binary serialization, you need to import the System.Runtime.Serialization.Formatters.Binary
namespace.
The Serialize()
function takes in a single parameter (the BookMark
object to serialize) and returns a MemoryStream
object representing the serialized BookMark
object. You use the BinaryFormatter
class from the System.Runtime.Serialization.Formatters.Binary
namespace to serialize an object. One side effect of this function is that it also serializes the BookMark
object to file, using the FileStream
class.
Before you serialize an object, you need to prefix the class that you want to serialize name with the [Serializable]
attribute:
[Serializable]
class BookMark {
private DateTime _dateCreated;
public BookMark() {
_dateCreated = DateTime.Now;
}
public DateTime GetDateCreated() {
return _dateCreated;
}
public string URL { get; set; }
public string Description { get; set; }
public BookMark NextURL { get; set; }
}
The following statement serializes the bm1 BookMark
object, using the Serialize()
function:
static void Main(string[] args) {
BookMark bm1, bm2;
bm1 = new BookMark {
URL = "http://www.amazon.com",
Description = "Amazon.com Web site"
};
bm2 = new BookMark() {
URL = "http://www.wrox.com",
Description = "Wrox.com Web site",
NextURL = null
};
//---link the first BookMark to the next---
bm1.NextURL = bm2;
//========Binary Serialization=========
//---serializing an object graph into a memory stream---
MemoryStream ms = Serialize(bm1);
}
To prove that the object is serialized correctly, you deserialize the memory stream (that is, "unflatten" the data) and assign it back to a BookMark
object:
static void Main(string[] args) {
BookMark bm1, bm2;
bm1 = new BookMark {
URL = "http://www.amazon.com",
Description = "Amazon.com Web site"
};
bm2 = new BookMark() {
URL = "http://www.wrox.com",
Description = "Wrox.com Web site",
NextURL = null
};
//---link the first BookMark to the next---
bm1.NextURL = bm2;
//========Binary Serialization=========
//---serializing an object graph into a memory stream---
MemoryStream ms = Serialize(bm1);
//---deserializing a memory stream into an object graph---
BookMark bm3 = Deserialize(ms);
}
Here is the definition for the DeSerialize()
function:
static void Main(string[] args) {
//...
}
static MemoryStream Serialize(BookMark bookMark) {
//...
}
static BookMark Deserialize(MemoryStream ms) {
BinaryFormatter formatter = new BinaryFormatter();
return (BookMark)formatter.Deserialize(ms);
}
To display the values of the deserialized BookMark object, you can print out them out like this:
static void Main(string[] args) {
BookMark bm1, bm2;
bm1 = new BookMark {
URL = "http://www.amazon.com",
Description = "Amazon.com Web site"
};
bm2 = new BookMark() {
URL = "http://www.wrox.com",
Description = "Wrox.com Web site",
NextURL = null
};
//---link the first BookMark to the next---
bm1.NextURL = bm2;
//========Binary Serialization=========
//---serializing an object graph into a memory stream---
MemoryStream ms = Serialize(bm1);
}
To prove that the object is serialized correctly, you deserialize the memory stream (that is, "unflatten" the data) and assign it back to a BookMark
object:
static void Main(string[] args) {
BookMark bm1, bm2;
bm1 = new BookMark {
URL = "http://www.amazon.com",
Description = "Amazon.com Web site"
};
bm2 = new BookMark() {
URL = "http://www.wrox.com",
Description = "Wrox.com Web site",
NextURL = null
};
//---link the first BookMark to the next---
bm1.NextURL = bm2;
//========Binary Serialization=========
//---serializing an object graph into a memory stream---
MemoryStream ms = Serialize(bm1);
//---deserializing a memory stream into an object graph---
BookMark bm3 = Deserialize(ms);
//---print out all the bookmarks---
BookMark tempBookMark = bm3;
do {
Console.WriteLine(tempBookMark.URL);
Console.WriteLine(tempBookMark.Description);
Console.WriteLine(tempBookMark.GetDateCreated());
Console.WriteLine(" ");
tempBookMark = tempBookMark.NextURL;
} while (tempBookMark != null);
Console.ReadLine();
}
If the objects are serialized and deserialized correctly, the output is as shown in Figure 11-12.
Figure 11-12
But what does the binary stream look like? To answer that question, take a look at the c:BookMarks.dat
file that you have created in the process. To view the binary file, simply drag and drop the BookMarks.dat
file into Visual Studio 2008. You should see something similar to Figure 11-13.
Figure 11-13
A few observations are worth noting at this point:
? Private variables and properties are all serialized. In binary serialization, both the private variables and properties are serialized. This is known as deep serialization, as opposed to shallow serialization in XML serialization (which only serializes the public variables and properties). The next section discusses XML serialization.
? Object graphs are serialized and preserved. In this example, two BookMark
objects are linked, and the serialization process takes care of the relationships between the two objects.
There are times when you do not want to serialize all of the data in your object. If you don't want to persist the date and time that the BookMark
objects are created, for instance, you can prefix the variable name (that you do not want to serialize) with the [NonSerialized]
attribute:
[Serializable]
class BookMark {
[NonSerialized]
private DateTime _dateCreated;
public BookMark() {
_dateCreated = DateTime.Now;
}
public DateTime GetDateCreated() {
return _dateCreated;
}
public string URL { get; set; }
public string Description { get; set; }
public BookMark NextURL { get; set; }
}
The dateCreated
variable will not be serialized. Figure 11-14 shows that when the dateCreated
variable is not serialized, its value is set to the default date when the object is deserialized.
Figure 11-14
- Serialization
- Reading Binary Data
- Binary search
- Adaptable Binary Function
- Binary Predicate
- Adaptable Binary Predicate
- 2. Binary – the way micros count
- 13.5. Binary Utilities
- 13.6. Miscellaneous Binary Utilities
- 1.6 Converting Binary Numbers into Decimal
- 1.7 Converting Decimal Numbers into Binary
- 1.8 Converting Binary Numbers into Hexadecimal