2011-08-26 12 views
7

Sto provando a utilizzare Protobuf-net per salvare e caricare i dati su disco ma si è bloccato.Utilizzare Protobuf-net per lo streaming di file di dati di grandi dimensioni come IEnumerable

Ho un portafoglio di risorse che ho bisogno di elaborare, e voglio essere in grado di farlo il più velocemente possibile. Posso già leggere da un CSV ma sarebbe più veloce usare un file binario, quindi sto esaminando Protobuf-Net.

Non riesco a inserire tutte le risorse in memoria, quindi voglio eseguirle in streaming, non caricarle tutte in memoria.

Quindi quello che devo fare è esporre un ampio set di record come un oggetto IEnumerable. È possibile con Protobuf-Net? Ho provato un paio di cose ma non sono riuscito a farlo funzionare.

La serializzazione sembra funzionare, ma non sono stato in grado di leggerli di nuovo, ottengo 0 asset indietro. Qualcuno potrebbe indicarmi la direzione giusta per favore? Osservato i metodi nella classe Serializer ma non è possibile trovare nessuno che copra questo caso. Questo caso d'uso è supportato da Protobuf-net? A proposito, sto usando la V2.

Grazie in anticipo,

Gert-Jan

Ecco alcuni esempi di codice ho provato:

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

Spiacente non ho potuto Aiuto- avuto un paio di giorni di distanza. Sono contento che tu abbia trovato la risposta. –

+0

nessuna preoccupazione non ci è voluto molto. Un grande ringraziamento a te per (ri) scrivere tutto! – gjvdkamp

risposta

7

capito. Per deserializzare utilizzare PrefixBase.Base128 apparentemente is the default.

Ora funziona come un fascino!

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 :-) 
     } 
Problemi correlati