我正在尝试使用Protobuf-net来保存数据并将数据加载到磁盘但却卡住了。
我有一个我需要处理的资产组合,我希望能够尽快做到这一点。我已经可以从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 :(得分: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 :-)
}