2011-08-26 67 views
7

我試圖使用Protobuf-net來保存和加載數據到磁盤,但卡住了。使用Protobuf-net作爲IEnumerable流式傳輸大型數據文件

我有一個需要處理的資產組合,而且我希望能夠儘可能快地做到這一點。我已經可以從CSV中讀取數據,但使用二進制文件會更快,所以我正在研究Protobuf-Net。

我無法將所有資產放入內存中,因此我想對它們進行流式處理,而不是將它們全部加載到內存中。

因此,我需要做的是將大量記錄作爲IEnumerable公開。 Protobuf-Net可能嗎?我已經嘗試了幾件事,但一直無法運行。

序列化似乎工作,但我一直無法再讀回他們,我得到0資產回來。請有人指出我正確的方向嗎?查看Serializer類中的方法,但無法找到涵蓋此案例的任何方法。我這個用Protobuf-net支持的用例嗎?順便說一句,我正在使用V2。

由於提前,

格特 - 揚

這是我嘗試了一些示例代碼:

public partial class MainWindow : Window { 

    // Generate x Assets 
    IEnumerable<Asset> GenerateAssets(int Count) { 
     var rnd = new Random(); 
     for (int i = 1; i < Count; i++) { 
      yield return new Asset { 
       ID = i, 
       EAD = i * 12345, 
       LGD = (float)rnd.NextDouble(), 
       PD = (float)rnd.NextDouble() 
      }; 
     } 
    } 

    // write assets to file 
    private void Write(string path, IEnumerable<Asset> assets){ 
     using (var file = File.Create(path)) { 
      Serializer.Serialize<IEnumerable<Asset>>(file, assets); 
     } 
    } 

    // read assets from file 
    IEnumerable<Asset> Read(string path) { 
     using (var file = File.OpenRead(path)) { 
      return Serializer.DeserializeItems<Asset>(file, PrefixStyle.None, -1); 
     } 
    } 

    // try it 
    private void Test() { 
     Write("Data.bin", GenerateAssets(100)); // this creates a file with binary gibberish that I assume are the assets 
     var x = Read("Data.bin"); 
     MessageBox.Show(x.Count().ToString()); // returns 0 instead of 100 
    } 

    public MainWindow() { 
     InitializeComponent(); 
    } 

    private void button2_Click(object sender, RoutedEventArgs e) { 
     Test(); 
    } 
} 

[ProtoContract] 
class Asset { 

    [ProtoMember(1)] 
    public int ID { get; set; } 

    [ProtoMember(2)] 
    public double EAD { get; set; } 

    [ProtoMember(3)] 
    public float LGD { get; set; } 

    [ProtoMember(4)] 
    public float PD { get; set; } 
} 
+0

抱歉,我不能幫助 - 過了幾天了。很高興你找到答案。 –

+0

不用擔心沒有太長時間。非常感謝你(重寫)整個事情! – gjvdkamp

回答

7

想通了。要反序列化使用PrefixBase.Base128很明顯is the default

現在它就像一個魅力!

GJ

 using (var file = File.Create("Data.bin")) { 
      Serializer.Serialize<IEnumerable<Asset>>(file, Generate(10)); 
     } 

     using (var file = File.OpenRead("Data.bin")) { 
      var ps = Serializer.DeserializeItems<Asset>(file, PrefixStyle.Base128, 1); 
      int i = ps.Count(); // got them all back :-) 
     } 
相關問題