如何使用protobuf-net进行xml序列化?

时间:2015-09-29 11:52:26

标签: c# serialization xml-serialization protobuf-net xmlserializer

也许我误解了序列化的东西。我想以最快的方式序列化我的.net对象。我做了一些谷歌搜索我找到了protobuf。 Myfirstquestion是ProtoBuf.Net具有xml serailization的能力。如果它有,我可以用它来进行xml序列化。

我的模特:


    [XmlType]
public class CT {
    [XmlElement(Order = 1)]
    public int Foo { get; set; }
}
[XmlType]
public class TE {
    [XmlElement(Order = 1)]
    public int Bar { get; set; }
}
[XmlType]
public class TD {
    [XmlElement(Order = 1)]
    public List CTs { get; set; }
    [XmlElement(Order = 2)]
    public List TEs { get; set; }
    [XmlElement(Order = 3)]
    public string Code { get; set; }
    [XmlElement(Order = 4)]
    public string Message { get; set; }
    [XmlElement(Order = 5)]
    public DateTime StartDate { get; set; }
    [XmlElement(Order = 6)]
    public DateTime EndDate { get; set; }
}

我的序列化器:

            CT ct = new CT() { Foo = 1 };
        List<CT> list = new List<CT>();
        list.Add(ct);
        TE te = new TE() { Bar = 2 };
        List<TE> list2 = new List<TE>();
        list2.Add(te);
        TD td = new TD() { Code = "Test",Message = "Yusuf",StartDate = DateTime.Now,EndDate = DateTime.Now,CTs = list,TEs = list2 };
        List<TD> list3 = new List<TD>();
        list3.Add(td);
        Stopwatch stopwatch5 = new Stopwatch();
        stopwatch5.Start();

        string str = String.Empty;
             using (MemoryStream stream = new MemoryStream()) 
        {
            byte[] data =  Serialize(list3);
            XmlDocument doc = new XmlDocument();
            string xml = Encoding.UTF8.GetString(data); <--SHOULD CREATE XML
            doc.LoadXml(xml);
           // str = Convert.ToBase64String(stream.GetBuffer(),0,(int)stream.Length); 
        } 
        stopwatch5.Stop();
        Console.WriteLine(((double)(stopwatch5.Elapsed.TotalMilliseconds * 1000000) / 1000000).ToString("0.00 ns"));
        Console.Read();

    }
    public static byte[] Serialize(List<TD> tData) {
        using(var ms = new MemoryStream()) {
            ProtoBuf.Serializer.Serialize(ms,tData);
            return ms.ToArray();
        }
    }

    public static List<TD> Deserialize(byte[] tData) {
        using(var ms = new MemoryStream(tData)) {
            return ProtoBuf.Serializer.Deserialize<List<TD>>(ms);
        }
    }

它应该创建xml作为&#34;的结果。 string xml = Encoding.UTF8.GetString(data);&#34;。但不是。我如何产生xml结果?

2 个答案:

答案 0 :(得分:3)

协议缓冲区不会将对象序列化为XML。
它产生二进制数据。它有自己的一套属性 请检查此answer

Protobuf-net的序列化/反序列化比XML快吗?是的,by far 但是,对于大多数任务, XmlSerializer足够快。 使用它时应该提醒的是:

  • XmlSerializer实例正在动态生成代码并将此代码编译为程序集。
  • 然后,使用此生成的程序集快速序列化和反序列化对象。
  • 所以你应该缓存XmlSerializer的实例(并避免重新创建它们)
  • 你可以通过调用Serialize和Deserialize来添加一个热身,以初始化内部对象并jit它们。

您甚至可以自己生成自动生成的程序集,但是每次更改对象时都应该记住重新生成(可以使用MsBuild任务自动生成)。 您还可以进一步优化:

答案 1 :(得分:0)

xml的根级别只能有一个标记。因此,TD不能是列表,或者您必须在List周围有一个外部标记。此代码有效

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            TD td = new TD()
            {
                Code = "Test",
                Message = "Yusuf",
                StartDate = DateTime.Now,
                EndDate = DateTime.Now,
                CTs = new List<CT>() {
                    new CT() { Foo = 1},
                    new CT() { Foo = 2},
                    new CT() { Foo = 3},
                },
                TEs = new List<TE>() {
                    new TE() { Bar = 1},
                    new TE() { Bar = 2},
                    new TE() { Bar = 3},
                }
            };

           using (MemoryStream stream = new MemoryStream()) 
            {
                byte[] data =  Serialize(td);
                XmlDocument doc = new XmlDocument();
                string xml = Encoding.UTF8.GetString(data); 
                doc.LoadXml(xml);
               // str = Convert.ToBase64String(stream.GetBuffer(),0,(int)stream.Length); 
            } 

        }
        public static byte[] Serialize(TD tData)
        {
            using (var ms = new MemoryStream())
            {
                XmlSerializer serializer = new XmlSerializer(typeof(TD));
                serializer.Serialize(ms, tData);
                return ms.ToArray();
            }
        }

        public static TD Deserialize(byte[] tData)
        {
            using (var ms = new MemoryStream(tData))
            {
                XmlSerializer xs = new XmlSerializer(typeof(TD));
                return (TD)xs.Deserialize(ms);
            }
        }
    }
    [XmlRoot("CT")]
    public class CT
    {
        [XmlElement(ElementName = "Foo", Order = 1)]
        public int Foo { get; set; }
    }
    [XmlRoot("TE")]
    public class TE
    {
        [XmlElement(ElementName = "Bar", Order = 1)]
        public int Bar { get; set; }
    }
    [XmlRoot("TD")]
    public class TD
    {
        [XmlElement(ElementName = "CTs",  Order = 1)]
        public List<CT> CTs { get; set; }
        [XmlElement(ElementName = "TEs", Order = 2)]
        public List<TE> TEs { get; set; }
        [XmlElement(ElementName = "Code", Order = 3)]
        public string Code { get; set; }
        [XmlElement(ElementName = "Message", Order = 4)]
        public string Message { get; set; }
        [XmlElement(ElementName = "StartDate", Order = 5)]
        public DateTime StartDate { get; set; }
        [XmlElement(ElementName = "EndDate", Order = 6)]
        public DateTime EndDate { get; set; }
    }
}
​