Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反序列化二进制文件的一部分_C#_Serialization - Fatal编程技术网

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。