C# 反序列化二进制文件的一部分
可以反序列化二进制文件的一部分吗 基本上我有一个类似于下面的对象,我将其序列化为一个二进制文件C# 反序列化二进制文件的一部分,c#,serialization,C#,Serialization,可以反序列化二进制文件的一部分吗 基本上我有一个类似于下面的对象,我将其序列化为一个二进制文件 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) } 公共类MyObj
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)
}
公共类MyObject
{
公共字符串名称{get;set;}
公共int值{get;set;}
公共IList{get;set;}//此处有大量数据(以kB为顺序)
}
我希望能够通过填充列表视图
以进行文件选择,从而仅反序列化名称
和值
,然后在需要时反序列化文件的其余部分(即,用户从列表视图
中选择该文件)
一如既往,我们非常感谢任何帮助,如果建议使用任何第三方库,它们将需要能够在商业环境中自由使用。将
名称
和值
放入一个超类并分别序列化如何
或者,您可以维护一个字典并将其序列化为一个文件。protobuf-net可以做到这一点,因为它与特定类型无关;例如:
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(),
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);
}
}
}
使用ProtoBuf;
使用System.Collections.Generic;
使用System.IO;
[原始合同]
公共类MyOtherObject{}
[原始合同]
公共类MyObject
{
[原成员(1)]
公共字符串名称{get;set;}
[原成员(2)]
公共int值{get;set;}
[原成员(3)]
公共IList项{get;set;}
}
[原始合同]
公共类MyObjectLite
{
[原成员(1)]
公共字符串名称{get;set;}
[原成员(2)]
公共int值{get;set;}
}
静态类程序
{
静态void Main()
{
var obj=新的MyObject
{
Name=“abc”,
值=123,
项目=新列表
{
新建MyOtherObject(),
新建MyOtherObject(),
新建MyOtherObject(),
新建MyOtherObject(),
}
};
使用(var file=file.Create(“foo.bin”))
{
Serializer.Serialize(文件,obj);
}
肌球蛋白;
使用(var file=file.OpenRead(“foo.bin”))
{
lite=序列化程序。反序列化(文件);
}
}
}
但如果您不想要两种不同的类型,和/或不想添加属性,也可以这样做:
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), false).Add("Name", "Value");
}
static void Main()
{
var obj = new MyObject
{
Name = "abc",
Value = 123,
Items = new List<MyOtherObject>
{
new MyOtherObject(),
new MyOtherObject(),
new MyOtherObject(),
new MyOtherObject(),
}
};
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));
}
}
}
使用ProtoBuf.Meta;
使用System.Collections.Generic;
使用System.IO;
公共类MyOtherObject{}
公共类MyObject
{
公共字符串名称{get;set;}
公共int值{get;set;}
公共IList项{get;set;}
}
静态类程序
{
静态只读RuntimeTypeModel、fatModel、liteModel;
静态程序()
{
//配置模型
fatModel=TypeModel.Create();
fatModel.Add(typeof(MyOtherObject),false);
添加(typeof(MyObject),false)。添加(“名称”、“值”、“项”);
liteModel=TypeModel.Create();
liteModel.Add(typeof(MyOtherObject),false);
Add(typeof(MyObject),false);
}
静态void Main()
{
var obj=新的MyObject
{
Name=“abc”,
值=123,
项目=新列表
{
新建MyOtherObject(),
新建MyOtherObject(),
新建MyOtherObject(),
新建MyOtherObject(),
}
};
使用(var file=file.Create(“foo.bin”))
{
序列化(文件,obj);
}
MyObject-lite;
使用(var file=file.OpenRead(“foo.bin”))
{
lite=(MyObject)liteModel.Deserialize(
文件,null,typeof(MyObject));
}
}
}
可能值得一提的是,您首先是如何序列化文件的。这里有一个类似的问题:可能包含您正在寻找的答案。只是想确认一下,列表视图项代表二进制文件的部分,您只想加载用户选择的部分?@musefan我在问题中说过,我将更新以使其更清楚(P.S.love Muse)我在这里看到的问题是:大多数支持将部分数据读回(读回不同类型)的序列化程序将不支持对象/IList
+1。从同一个字节数组中可以得到两个不同的模型,这很好。但是,有没有一种方法可以在需要时将“rest”反序列化为lite
?如果我正确理解这个解决方案,当您需要完整对象时,它要求您丢弃lite
,并使用fatModel
反序列化一个全新的对象。因此,在您的第一个示例中,只要属性名称和类型以及ProtoMember
值相同,它不在乎反序列化到什么对象吗?在某些情况下,是的(protobuf是可合并的),但在一般情况下,我会说这是错误的方法。@dav_I实际上,protobuf从不使用名称-重要的只是键(1,2,3)。在第二个示例中,该语法只是“将它们配置为1,2,3,…”+1,✓: 好吧,我还没有实现这个,但它似乎是最好的解决方案。你在这个库中做得很好,@MarcGravel。