如何使用protobuf在C#中序列化一个文件中的多个对象

时间:2013-12-04 07:15:18

标签: c# serialization protocol-buffers

我有类Person,我希望有几个实例,我想在一个文件中序列化它们。我该怎么做? 我不能创建Person列表然后序列化它。 我希望可以反序列化一个保存的类实例(例如保存的第四个实例)。我怎么能这样做?

人类:

[ProtoContract]
class Person
{
    public Person()
    { }
    [ProtoMember(1)]
    public int a;
    public Person(int d)
    {
        a = d;
    }
}

序列化的方法:

public void serialize()
    { 
        Person p1 = new Person(1);
        Person p2 = new Person(2);
        Person p3 = new Person(3);
        Person p4 = new Person(4);
        Person p5 = new Person(5);
        FileStream file = File.Create("person.bin") ;
        Serializer.Serialize(file, p1);
        Serializer.Serialize(file, p2);
        Serializer.Serialize(file, p3);
        Serializer.Serialize(file, p4);
        Serializer.Serialize(file, p5);
        file.Close();
    }

反序列化的方法:

public void deserialize()
    {
        Person nP1, nP2,nP3,nP4,nP5;
        FileStream file = File.OpenRead("person.bin");
        nP1 = Serializer.Deserialize<Person>(file);
        nP2 = Serializer.Deserialize<Person>(file);
        nP3 = Serializer.Deserialize<Person>(file);
        nP4 = Serializer.Deserialize<Person>(file);
        nP5 = Serializer.Deserialize<Person>(file);
        file.Close();
    }

1 个答案:

答案 0 :(得分:5)

“协议缓冲区”格式未终止(这是由Google的设计,因此可以通过串联合并消息)。这样做的副作用是,如果您只是多次序列化,则反序列化会将其全部视为一条消息。幸运的是,protobuf-net可以很容易地做你想做的事情:

Serializer.SerializeWithLengthPrefix(file, p1, PrefixStyle.Base128, 1);
Serializer.SerializeWithLengthPrefix(file, p2, PrefixStyle.Base128, 1);
// etc

nP1 = Serializer.DeserializeWithLengthPrefix<Person>(file,PrefixStyle.Base128,1);
nP2 = Serializer.DeserializeWithLengthPrefix<Person>(file,PrefixStyle.Base128,1);
// etc

另一种方法是创建一个包装器对象 - 一个PersonWrapperPeople或任何你想要调用它的东西 - 封装一切你想序列化。这可以是List<Person>,也可以是单个属性Person0Person1等。

var wrapper = new PersonWrapper { ... };
Serializer.Serialize(file, wrapper);
//...
var wrapper = Serializer.Deserialize<PersonWrapper>(file);

最后,您可以序列化一个列表:

List<Person> people = ...
Serializer.Serialize(file, people);
...
var people = Serializer.Deserializer<List<Perosn>>(file);