我有一个约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规范假定你只是将值连接到一个对象.上面提到的两种方法避免了这个问题.