首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >protobuf-csharp-port -从文件流式传输记录有点像LINQ-to-XML中的轴函数

protobuf-csharp-port -从文件流式传输记录有点像LINQ-to-XML中的轴函数
EN

Stack Overflow用户
提问于 2011-03-19 02:21:50
回答 2查看 713关注 0票数 1

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

代码语言:javascript
复制
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();
    }
}

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

在XML世界中,我会使用一个轴函数来流式传输元素。是否可以流式传输地址簿模型对象中的记录?或者,也许有另一种方法可以实现这一点,以便更有效地使用内存?

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-19 02:55:52

是的,你可以流读和写。

有一个受官方Java API支持的版本,在我的C# API中也有一个使用WriteDelimitedTo/ParseDelimitedFrom的版本。

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

票数 2
EN

Stack Overflow用户

发布于 2011-03-19 02:36:44

我不能评论这个实现,但在protobuf-net流媒体中是完全可能的。如果您想要流式传输的所有对象都是根对象的第一级子对象,那么您可以简单地迭代外部序列;如果它们都是同一类型,则使用Serializer.DeserializeItems<T>;如果涉及不同类型的对象,则使用Serializer.NonGeneric.TryDeaerializeWithLengthPrefix

如果您希望作为流处理的项位于树的中间,则可以提供另一种接收模型;只需在伪集合上实现IEnumerable和Add(),它就可以通过您想要的任何应用程序接口(基于事件,例如类似于SAX )推送数据。

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

如果你想要一个更完整的例子,请让我知道。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5356236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档