我有一个简单的类,如
public class Customer{
public long Id;
public string Name;
....
}
我有一个List,我想使用protobuf-net对其进行序列化。请指导我简单有效的序列化和反序列化方法。
修改-1 我正在查看使用protobuf-net源代码的单元测试,它使用2种方式进行序列化,使用反射和使用Model(内部处理基于ToString的映射)。
我从源代码中得到的是我在源代码的项目文件夹e-ProtoBufNetWithModel中使用了与测试相同的技术并创建了一个TypeModel ......
public static TypeModel CreateModel()
{
RuntimeTypeModel model = TypeModel.Create();
model.Add(typeof(Customer), false)
.Add(1, "Id")
.Add(1, "Name");
TypeModel compiled = model.Compile();
return compiled;
}
问题区域
public static Stream SerializeUsingProtobuf(IList<Customer> pSource)
{
var model = CreateModel();
using (Stream memoryStream = new MemoryStream())
{
model.Serialize(memoryStream, pSource);
return memoryStream;
}
}
在TypeModel compiled = model.Compile();
上,它会引发异常
检测到重复的字段编号; 1
答案 0 :(得分:1)
https://code.google.com/p/protobuf-net/
短版 (另见旧主页)
序列化很痛苦。 protobuf-net旨在通过最少的更改(来自可选的.proto模式)轻松地在现有代码上使用,从而在各种.NET平台上实现快速和可移植的二进制序列化。
它不是“协议缓冲器实现恰好在.NET上”,而是“.NET序列化器碰巧使用协议缓冲区” - 重点是.NET用户熟悉(例如,工作)如果你愿意,可以使用可变的代码优先类。除了常规的protobuf设计之外,我还添加了一系列常用功能,以帮助满足.NET程序员的日常需求(继承,参考跟踪等)。
用法很简单;在最基本的层面上,只需从流中读取或写入流;见入门:
// write to a file
Serializer.Serialize(outputStream, person);
...
// read from a file
var person = Serializer.Deserialize<Person>(inputStream);
哦,它非常快;无论是CPU还是带宽。
如果你想在visual studio中使用.proto文件,有一些VS工具,但你不需要 - 你可以写一个类,告诉序列化器如何使用它(最常见的是添加一个几个属性,但这取决于你),并序列化。
https://code.google.com/p/protobuf-net/wiki/GettingStarted
序列化数据 由于“协议缓冲区”是二进制格式,protobuf-net主要基于Stream类;这使得可以简单地使用各种各样的实现。例如,要写入文件:
var person = new Person { Id = 12345,Name =“Fred”, 地址=新地址{ Line1 =“Flat 1”, Line2 =“The Meadows” } }; 使用(var file = File.Create(“person.bin”)){ Serializer.Serialize(文件,人); }
这将32字节文件写入“person.bin”。在上面可能并不明显,但Serialize是一种通用方法 - 该行也可以是:
using (var file = File.Create("person.bin")) {
Serializer.Serialize<Person>(file, person);
}
但是大多数时候我们可以让编译器的泛型类型推断为我们工作。
反序列化数据 我们还需要退回数据!
Person newPerson;
using (var file = File.OpenRead("person.bin")) {
newPerson = Serializer.Deserialize<Person>(file);
}
这将从“person.bin”中读取数据。注意我们需要告诉它这次的类型(the),否则代码非常相似。
答案 1 :(得分:1)
要序列化的每个字段都需要不同的标记(正整数)。而不是1和1,在调用Add时尝试使用1和2。或者更简单,只需添加(&#34; Id&#34;,&#34;名称&#34;);