如何使用 protobuf-net 进行 xml-序列化?
How to use protobuf-net for xml-serialization?
可能我对连载有什么误解。我想以最快的方式序列化我的 .net 对象。我做了一些谷歌搜索,我发现了 protobuf。我的第一个问题是 ProtoBuf.Net 具有 xml serailization.if 的能力,我可以将它用于 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 作为“string xml = Encoding.UTF8.GetString(data);”的结果。但是没有。我怎样才能产生 xml 结果?
您的 xml 的根级别只能有一个标签。所以要么 TD 不能是一个列表,要么你必须在列表周围有一个外部标记。此代码有效
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; }
}
}
协议缓冲区不会将对象序列化为 XML。
它产生二进制数据。而且它有自己的一套属性。
检查这个 answer
Protobuf-net 的 serialization/deserialization 比 XML 快吗?是的,by far.
但是 XmlSerializer 足够快 可以完成大多数任务。
不过在使用的时候需要提醒的是:
- XmlSerializer 实例正在动态生成代码并将此代码编译成程序集。
- 此生成的程序集随后用于非常快速地序列化和反序列化您的对象。
- 因此您应该缓存 XmlSerializer 的实例(并避免重新创建它们)
- 您可以通过调用 Serialize 和 Deserialize 来预热,以初始化内部对象并 jit 它们。
您甚至可以通过自己生成自动生成的程序集来更进一步,但是您应该记住每次更改对象时都要重新生成(它可以通过 MsBuild 任务自动生成)。
您还可以进一步优化:
- On Stack Overflow
- With Sgen
可能我对连载有什么误解。我想以最快的方式序列化我的 .net 对象。我做了一些谷歌搜索,我发现了 protobuf。我的第一个问题是 ProtoBuf.Net 具有 xml serailization.if 的能力,我可以将它用于 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 作为“string xml = Encoding.UTF8.GetString(data);”的结果。但是没有。我怎样才能产生 xml 结果?
您的 xml 的根级别只能有一个标签。所以要么 TD 不能是一个列表,要么你必须在列表周围有一个外部标记。此代码有效
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; }
}
}
协议缓冲区不会将对象序列化为 XML。
它产生二进制数据。而且它有自己的一套属性。
检查这个 answer
Protobuf-net 的 serialization/deserialization 比 XML 快吗?是的,by far.
但是 XmlSerializer 足够快 可以完成大多数任务。
不过在使用的时候需要提醒的是:
- XmlSerializer 实例正在动态生成代码并将此代码编译成程序集。
- 此生成的程序集随后用于非常快速地序列化和反序列化您的对象。
- 因此您应该缓存 XmlSerializer 的实例(并避免重新创建它们)
- 您可以通过调用 Serialize 和 Deserialize 来预热,以初始化内部对象并 jit 它们。
您甚至可以通过自己生成自动生成的程序集来更进一步,但是您应该记住每次更改对象时都要重新生成(它可以通过 MsBuild 任务自动生成)。 您还可以进一步优化:
- On Stack Overflow
- With Sgen