是否可以反序列化二进制文件的一部分?
基本上我有一个类似于下面的对象,我将其序列化为二进制文件.
@H_502_4@public class MyObject { public string Name { get; set; } public int Value { get; set; } public IList<MyOtherObject> { get; set; } // lots of data in here (order of kB-MB) }我想要的是能够通过填充ListView以进行文件选择来反序列化Name和Value,然后在需要时反序列化文件的其余部分(即用户从ListView中选择该文件).
与往常一样,任何帮助都非常感激,如果建议任何第三方库,他们需要能够在商业环境中自由使用.
解决方法
protobuf-net可以做到这一点,因为它与特定类型无关;例如:
@H_502_4@using ProtoBuf;
using System.Collections.Generic;
using System.IO;
[ProtoContract]
public class MyOtherObject { }
[ProtoContract]
public class MyObject
{
[ProtoMember(1)]
public string Name { get; set; }
[ProtoMember(2)]
public int Value { get; set; }
[ProtoMember(3)]
public IList<MyOtherObject> Items { get; set; }
}
[ProtoContract]
public class MyObjectLite
{
[ProtoMember(1)]
public string Name { get; set; }
[ProtoMember(2)]
public int Value { get; set; }
}
static class Program
{
static void Main()
{
var obj = new MyObject
{
Name = "abc",Value = 123,Items = new List<MyOtherObject>
{
new MyOtherObject(),new MyOtherObject(),}
};
using (var file = File.Create("foo.bin"))
{
Serializer.Serialize(file,obj);
}
MyObjectLite lite;
using (var file = File.OpenRead("foo.bin"))
{
lite= Serializer.Deserialize<MyObjectLite>(file);
}
}
}
但是如果你不想要两种不同的类型,和/或你不想要添加属性 – 那也可以这样做:
@H_502_4@using ProtoBuf.Meta; using System.Collections.Generic; using System.IO; public class MyOtherObject { } public class MyObject { public string Name { get; set; } public int Value { get; set; } public IList<MyOtherObject> Items { get; set; } } static class Program { static readonly RuntimeTypeModel fatModel,liteModel; static Program() { // configure models fatModel = TypeModel.Create(); fatModel.Add(typeof(MyOtherObject),false); fatModel.Add(typeof(MyObject),false).Add("Name","Value","Items"); liteModel = TypeModel.Create(); liteModel.Add(typeof(MyOtherObject),false); liteModel.Add(typeof(MyObject),"Value"); } static void Main() { var obj = new MyObject { Name = "abc",} }; using (var file = File.Create("foo.bin")) { fatModel.Serialize(file,obj); } MyObject lite; using (var file = File.OpenRead("foo.bin")) { lite = (MyObject)liteModel.Deserialize( file,null,typeof(MyObject)); } } }