65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Protobuf-net 进行 Silverlight 二进制序列化

starIconstarIconstarIconstarIconstarIcon

5.00/5 (8投票s)

2010 年 4 月 19 日

CPOL

3分钟阅读

viewsIcon

71455

downloadIcon

634

如何将纯 .NET 对象类序列化为快速二进制数据

引言

本文向您展示如何在 Silverlight 中将纯 .NET 对象类序列化为快速二进制数据。

背景

Silverlight 不提供纯二进制对象序列化。 虽然 DataContractSerializerXmlSerializer 是很好的序列化基础设施,但这些类都基于 XML。 The CustomBinarySerializer approach 是一种很好的二进制实现方法,但它需要为每个业务对象创建方便的类。

Protobuf-net

Protobuf-netGoogle Protobuf 的 C# 实现组件之一,它提供更紧凑和快速的纯 .NET 对象类的二进制序列化。 此外,该组件还支持 Silverlight 版本,使我们能够使用 SocketAsyncEventArgs 类,将一些数据保存和加载到本地磁盘、通过 HTTP 的远程 WCF 服务器或低级 TCP/IP 套接字。 它为原始类型生成原始级别的 byte[],但 Silverlight 序列化器基于 XML 数据。

Protobuf-csharp-port 是 Protobuf 的另一个很棒的 C# 版本。 它遵循 Java 实现的大部分标准 API 和编码模式。 它为每个业务类使用工具生成的编解码器。 但是,我选择 Protobuf-net 作为 Protobuf 的基本二进制编解码器引擎,因为它遵循基本的 .NET 架构。

它使用属性反射,但其性能足够快。 此外,该引擎使我们能够更轻松地使用干净的纯业务对象类和基本流类。 在 Silverlight 中使用 Protobuf-net 程序集很容易,而使用 Silverlight 中的 Protobuf-csharp-port 则需要进行一些代码修复任务。

Silverlight IsolatedStorage(独立存储)

在 Silverlight 中,我们可以使用 IsolatedStorage 将一些数据存储到我们的本地硬盘。 存储空间和位置受到限制,但 Silverlight 浏览器外环境可以解锁该限制。

我们将使用 IsolatedStorage 来保存和加载我们的数据,并使用 Protobuf-Net 二进制序列化。

Using the Code

设置项目

我们将使用 VS2008 SP1 和 Silverlight 3。 我们应该添加带有网站测试选项的 Silverlight 应用程序项目模板。 以下图像是我们项目的最终布局。

您可以在任何“Silverlight 类库或应用程序”项目类型中使用 protobuf-net 程序集。 此 SLBufferSerializer 是一个 Silverlight 应用程序项目,带有 VS2008 自动生成的 Silverlight ASP.NET 网站。

确保在网站中设置起始页以使用 F5。 请参阅此图片,了解如何设置网站项目属性。

Person 业务类 (Person.cs)

让我们使用 ProtoBuf-net 的“ProtoContract”和“ProtoMember”属性创建 Person 纯类。 这种方法与 XMLSerializer 方法非常相似。 以下属性的数字是 Google 的 protobuf 所需的顺序。

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 页面 (MainPage.xaml)

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

IsolatedStorage 助手方法 (MainPage.xaml.cs)

这些是将 Protobuf-net 序列化到 IsolatedStorage 的助手方法。 编解码器引擎基本上使用 Stream 实现,因此 IsolatedStorageStream 类也可用。

您还可以将这些方法放置到另一个 static 助手类

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

实现代码隐藏逻辑 (MainPage.xaml.cs)

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

...
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<Person>(fileName, person);
            }
            catch (IsolatedStorageException)
            {
            }
        }
        private void btnTest_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Person person = LoadFromStorage<Person>(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)
            {
            }
        }
 ...
    }
}

最终的 Silverlight 结果屏幕

这是反序列化后执行的屏幕。

参考文献

有关更多信息,请点击以下链接

© . All rights reserved.