在Silverlight中实现快速二进制数据序列化

在现代Web开发中,数据的序列化与反序列化是常见的需求。Silverlight作为一种富互联网应用程序框架,虽然提供了基于XML的序列化机制,如DataContractSerializer和XmlSerializer,但这些机制并不支持纯二进制对象序列化。为了实现更高效的数据存储和传输,可以考虑使用Protobuf-net,这是一个基于Google Protobuf的C#实现,它提供了更紧凑且快速的二进制序列化方式。

Protobuf-net不仅支持纯.NET对象类的二进制序列化,还特别提供了Silverlight版本,使得可以将数据保存到本地磁盘,或者通过HTTP、TCP/IP套接字等方式加载到远程WCF服务器。Protobuf-net生成的是原始级别的byte[],这对于处理基本数据类型非常有用,尽管Silverlight的序列化器基于XML数据。

Protobuf-csharp-port是另一个优秀的C#版本的Protobuf实现,它遵循Java实现的大多数标准API和编码模式。它使用工具生成的编解码器为每个业务类服务。然而,选择了Protobuf-net作为Protobuf的基础二进制编解码引擎,因为它遵循了基本的.NET架构。它使用属性反射,但其性能足够快。此外,该引擎使能够更容易地使用干净的纯业务对象类和基本流类。在Silverlight中使用Protobuf-net程序集很容易,而使用Protobuf-csharp-port则需要进行一些代码修复工作。

在Silverlight中,可以使用IsolatedStorage将数据存储到本地硬盘。存储空间和位置是有限的,但在Silverlight Out-Of-Browser环境中可以解除这些限制。将使用IsolatedStorage与Protobuf-Net二进制序列化一起保存和加载数据。

项目设置

将使用VS2008 SP1和Silverlight 3。应该添加Silverlight应用程序项目模板,并选择网站测试选项。项目最终布局的图像可以在本文的源代码中查看。可以在任何“Silverlight类库或应用程序”项目类型中使用protobuf-net程序集。这个SLBufferSerializer是一个Silverlight应用程序项目,它由VS2008自动生成Silverlight ASP.NET网站。

确保在网站上设置起始页面以使用F5。查看如何设置网站项目属性的图像。

业务类设计

让创建一个带有ProtoBuf-net的‘ProtoContract’和‘ProtoMember’属性的Person纯类。这种方法与XMLSerializer方法非常相似。下面属性的数字是Google的protobuf所要求的顺序。

C# using System; using ProtoBuf; namespace SLBufferSerializer { [ProtoContract] public class Person { [ProtoMember(1)] public int Id { get; set; } [ProtoMember(2)] public string Name { get; set; } [ProtoMember(3)] public Address Address { get; set; } } [ProtoContract] public class Address { [ProtoMember(1)] public string Line1 { get; set; } [ProtoMember(2)] public string Line2 { get; set; } } }

设计XAML页面

这是在Visual Studio中设计主显示XAML页面后的预览设计。可以在本文的源代码中查看详细的XAML代码。

IsolatedStorage辅助方法

这些是Protobuf-net序列化到IsolatedStorage的辅助方法。编解码引擎基本上使用流实现,因此IsolatedStorageStream类也是可用的。也可以将这些方法放置在另一个静态帮助类中:

C# private static void SaveToStorage(string filePath, T instance) { using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication()) { using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.CreateNew, storage)) { Serializer.Serialize(stream, instance); } } } private static T LoadFromStorage(string filePath) { using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication()) { using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, storage)) { return Serializer.Deserialize(stream); } } }

实现代码逻辑

初始化一个person实例。让保存和加载person实例的序列化数据。

C# ... using ProtoBuf; namespace SLBufferSerializer { public partial class MainPage : UserControl { private readonly string fileName = "test.txt"; public MainPage() { InitializeComponent(); this.ProtobufSerialize(); } private void ProtobufSerialize() { var person = new Person { Id = 12345, Name = "Fred", Address = new Address { Line1 = "Flat 1", Line2 = "The Meadows" } }; try { SaveToStorage(fileName, person); } catch (IsolatedStorageException) { } } private void btnTest_Click(object sender, RoutedEventArgs e) { try { Person person = LoadFromStorage(fileName); this.txtStatus.Text = "De-Serialized...."; this.txt1.Text = person.Id.ToString(); this.txt2.Text = person.Name; this.txt3.Text = person.Address.Line1; this.txt4.Text = person.Address.Line2; } catch (IsolatedStorageException) { } } ... } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485