2011-02-14 64 views
5

我使用protobuf-net序列化了一系列對象。使用protobuf-net進行質量過濾

理論上,.bin文件可以包含數百萬個對象。

假設的目的是含有以下一類:

public string EventName; 

我必須採取一個查詢並創建包含匹配查詢的對象列表。 使用LINQ從序列化文件中提取匹配對象的正確方法是什麼?

回答

5

protobuf格式是一個項目的線性序列;任何索引等你的方式只能分開申請。但是,IEnumerable<T>可用;您可能會發現:

var item = Serializer.DeserializeItems<YourType>(source) 
     .First(item => item.Id == id); 

很好地完成了這項工作;這個:

  • 是懶洋洋的假脫機;每個項目單獨產生,因此您不需要內存過剩
  • 被短路;如果該項目被發現在附近展開,它會迅速退出

或者多個項目:

var list = Serializer.DeserializeItems<YourType>(source) 
    .Where(item => item.Foo == foo); 

(如果你希望緩衝相匹配的項目添加ToList以上的TE結束在內存中,或者在沒有ToList的情況下使用,如果你只想以forwards-only的方式解析它)

0

不幸的是,沒有一個。爲了使用LINQ,您的對象必須實現IQueryable<T>IEnumerable<T>。除非有LINQ提供程序可以提供IQueryable<T>接口到您的.bin文件,你要麼必須:

  • 反序列化文件到內存中,並使用LINQ到對象IEnumerable<T>
  • 寫下您的LINQ提供者可以提供IQueryable<T>(如果文件很大,這可能是唯一可行的選擇),它可以在不加載整個文件的情況下處理文件。
+0

DeserializeItems提供了一個好的工作`IEnumerable `API,然後 – 2011-02-14 19:29:47

+0

@Marc:它會出現這樣!我假定反序列化會將整個文件加載到內存中。很明顯,我錯了。 – 2011-02-14 19:51:04

+0

它會懶惰地從流中緩存它們(`yield return`) - 處理大數據量的理想選擇 – 2011-02-14 19:55:41

0

protobuf可以給你的文件內容作爲流IEnumerable<T>,所以你可以很容易地做到這一點。不幸的是,我不知道如何調用該方法,但在文檔中很容易找到。

1

如果你想添加一些投影在選定的元素列表上,你應該試試我的一個庫,https://github.com/Scooletz/protobuf-linq。它們也可以在NuGet上使用。 該庫極大地降低了反序列化開銷。在某些情況下,它可以降到原始查詢的50%。