2011-08-26 64 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 :-) 
     } 
相关问题