当前位置 : 主页 > 大数据 > 区块链 >

序列化 – 如何使用protobuf-net序列化/反序列化大型项目列表

来源:互联网 收集:自由互联 发布时间:2021-06-22
我有一个约5亿件物品的清单.如果我序列化单个项目而不是列表,我能够将其序列化为带有protobuf-net文件的文件 – 我无法将项目收集到价格列表中,然后序列化,因为我的内存不足.所以,我
我有一个约5亿件物品的清单.如果我序列化单个项目而不是列表,我能够将其序列化为带有protobuf-net文件的文件 – 我无法将项目收集到价格列表中,然后序列化,因为我的内存不足.所以,我必须一次序列化一条记录:

using (var input = File.OpenText("..."))
using (var output = new FileStream("...", FileMode.Create, FileAccess.Write))
{
    string line = "";
    while ((line = input.ReadLine()) != null)
    {
        Price price = new Price();
        (code that parses input into a Price record)

        Serializer.Serialize(output, price);
    }
}

我的问题是关于反序列化的部分.似乎Deserialize方法不会将流的位置移动到下一条记录.我试过了:

using (var input = new FileStream("...", FileMode.Open, FileAccess.Read))
{
    Price price = null;
    while ((price = Serializer.Deserialize<Price>(input)) != null)
    {
    }
}

我看到一个真实的价格记录,然后其余的是空记录 – 我得到Price对象,但所有字段都被初始化为默认值.

如何正确反序列化包含未序列化为列表的对象列表的流?

好消息! protobuf-net API就是针对这种情况而设置的.您应该看到一个与IEnumerable< T>一起使用的SerializeItems和DeserializeItems方法对,允许流入和流出.最简单的方法是通过源数据上的“迭代器块”来进行枚举.

如果由于某种原因,这是不方便的,那就是在每个项目的基础上使用SerializeWithLengthPrefix和DeserializeWithLengthPrefix 100%相同,指定(作为参数)字段:1和prefix-style:base-128.您甚至可以使用SerializeWithLengthPrefix进行写入,并使用DeserializeItems进行读取(只要使用字段1和base-128).

重新举例 – id必须在完全可重现的场景中看到它才能发表评论;实际上,我所期望的是你只返回一个对象,包含每个对象的组合值 – 因为没有length-prefix,protobuf规范假定你只是将值连接到一个对象.上面提到的两种方法避免了这个问题.

网友评论