protobuf-csharp-port – 从LINQ-to-XML中的一个类似于轴函数的文件中流式传输记录

我已经构建了protobuf-csharp-port附带的标准地址簿教程,我的代码如下:

class Program { static void Main(string[] args) { CreateData(); ShowData(); } private static void CreateData() { AddressBook.Builder abb = new AddressBook.Builder(); for (int i = 0; i < 2000000; i++) { Person.Builder pb = new Person.Builder(); pb.Id = i; pb.Email = "mytest@thisisatest.com"; pb.Name = "John" + i; abb.AddPerson(pb.Build()); } var ab = abb.Build(); var fs = File.Create("c:\\testaddressbook.bin"); ab.WriteTo(fs); fs.Close(); fs.Dispose(); } private static void ShowData() { var fs = File.Open("c:\\testaddressbook.bin", FileMode.Open, FileAccess.Read, FileShare.Read); CodedInputStream cis = CodedInputStream.CreateInstance(fs); cis.SetSizeLimit(Int32.MaxValue); AddressBook ab = AddressBook.ParseFrom(cis); Console.WriteLine("Person count: {0}", ab.PersonCount); for (int i = 0; i < ab.PersonCount; i++) Console.WriteLine("Name: " + ab.GetPerson(i).Name); Console.WriteLine("Person count: {0}", ab.PersonCount); fs.Close(); } } 

在写入数据时,它占用300 MB的RAM用于2m记录。 在阅读时,它占用大约415 MB的RAM。

在XML世界中,我将使用轴函数来流式传输元素。 是否可以流式传输通讯录模型对象中的记录? 或者可能还有另一种方法来实现这一目标以实现更高效的内存使用?

谢谢

是的,你可以流式传输阅读和写作。

官方Java API以及我的C#API支持使用WriteDelimitedTo / ParseDelimitedFrom

或者,您可以使用MessageStreamWriterMessageStreamIterator ,我在分隔的API出现之前将其引入到我的API中。

我无法评论该实现,但在protobuf-net流媒体中是完全可能的。 如果要传输的所有对象都是根对象的第一级子对象,那么您可以简单地遍历外部序列; 如果它们都是相同类型,则使用Serializer.DeserializeItems如果涉及不同类型的对象,则使用Serializer.DeserializeItems

如果要作为流处理的项目位于树的中间 ,则可以提供替代接收模型; 通过在假集合上实现IEnumerable和Add(),它可以通过您想要的任何API推送数据(基于事件,例如 – 像SAX一样)。

我还应该注意,您可以以完全相同的方式序列化流数据。 在任何时候都不需要具有完整的对象模型。

如果你想要一个更完整的例子,请告诉我。