【问题标题】:Thrift/Proto How to?节俭/原型如何?
【发布时间】:2012-03-10 17:02:09
【问题描述】:

我需要将一个包含 100000 个对象的大型数组序列化到一个文件中,但是在反序列化过程中,我想每次读取 1000 个对象。

目前我没有找到任何 Thrift 或 C# 协议缓冲区的好例子。请有人帮帮我。

问候

【问题讨论】:

    标签: c# serialization buffer protocol-buffers thrift


    【解决方案1】:

    protobuf-csharp-port 有MessageStreamIteratorMessageStreamWriter,它们允许您写出一个序列,然后在反序列化时迭代它们。然后你可以使用 LINQ to Objects 得到 1000 或任何你想要的。

    【讨论】:

      【解决方案2】:

      如果您使用 protobuf-net,则有一个方法 DeserializeItems(或类似方法)提供 IEnumerable<T> 实现,非缓冲,允许您随意使用项目(适用于 LINQ“Take”等)。如果原始序列化对象是对象列表/数组,则此方法非常有效。它还与 DeserializeWithLengthPrefix 方法完全兼容,该方法从流中读取单个对象而不会过度读取(因为它是长度前缀的日志,如果是数组/项目列表,就是这种情况是序列化的),允许您在“while”循环中执行相同的操作。如果您需要更完整的示例,请告诉我。

      例子:

      // write
      YourType[] array = ...;
      Serializer.Serialize(destination, array);
      
      // read
      List<YourType> batch = new List<YourType>(1000);
      foreach(var item in Serializer.DeserializeItems<YourType>(source)) {
          batch.Add(item);
          if(batch.Count == 1000) {
              ProcessBatch(batch);
              batch.Clear();
          }
      }
      if(batch.Count != 0) ProcessBatch(batch);
      

      还请注意,协议缓冲区是可附加的,因此要向文件添加更多数据,您只需查找文件末尾并开始写入更多数据。

      【讨论】:

      • 出于兴趣,我们的两种解决方案是否相互兼容?
      • 感谢您的快速回复,如果您能提供完整的示例,那就太好了。
      • @Jon mine 是,每个项目:一个 optional 标记为 varint,通常为“1”,然后是 varint 的长度,然后是有效负载。兼容吗?
      • @user1261267 没问题 - 我目前在手机上;可以稍后添加完整/测试示例,但添加粗略估计
      • @Jon 哎呀,我的意思是“标签装饰为字符串线型”,请注意它还支持大/小端 4 字节 int 长度前缀(没有标签/线型) ,因为很多人似乎都在使用它。
      猜你喜欢
      • 1970-01-01
      • 2014-03-24
      • 2012-11-28
      • 2019-03-31
      • 2016-08-19
      • 2015-10-18
      • 2013-02-28
      • 1970-01-01
      • 2016-03-09
      相关资源
      最近更新 更多