Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.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#_.net_Serialization_Clr - Fatal编程技术网

C# 如何序列化包含大量对象的对象?

C# 如何序列化包含大量对象的对象?,c#,.net,serialization,clr,C#,.net,Serialization,Clr,我正在使用c#和.NET4.5 我有一个类SomeData,它包含一个成员SomeEvents,这是一个字典。SomeData类还包含一组信息,例如数据生成的时间、生成数据的用户等 我正试图使用formatter.Serialize将SomeData对象保存到文件中,但当对象较大(例如1GB)时,遇到OutOfMemoryException 我读过的其他文章表明,内存不足问题是由于无法找到足够大的连续可用内存区域来生成要写入磁盘的数据造成的。我还读到,这是一种“错误”的序列化方式——我的假设是,

我正在使用c#和.NET4.5

我有一个类SomeData,它包含一个成员SomeEvents,这是一个字典。SomeData类还包含一组信息,例如数据生成的时间、生成数据的用户等

我正试图使用formatter.Serialize将SomeData对象保存到文件中,但当对象较大(例如1GB)时,遇到OutOfMemoryException

我读过的其他文章表明,内存不足问题是由于无法找到足够大的连续可用内存区域来生成要写入磁盘的数据造成的。我还读到,这是一种“错误”的序列化方式——我的假设是,如果我做得正确,CLR将按原样写入数据,而不是在保存数据之前尝试在内存中准备所有数据。也就是说,我确实看到在序列化操作失败之前创建了一个大文件,这意味着它正在编写

我尝试更改序列化操作以写入字典对象本身,而不是包含字典的对象-同样的问题,我得到了内存异常

问题:

  • 为什么Serialize会遇到这个内存问题——即使我给它一个Dictionary对象进行序列化——它肯定会按原样编写
  • 有更好的方法吗 以下是完全例外:

    无法保存文件:System.OutOfMemoryException:引发了类型为“System.OutOfMemoryException”的异常

    在System.Runtime.Serialization.ObjectedGenerator.Rehash()中

    在System.Runtime.Serialization.ObjectedGenerator.GetId(对象obj、布尔值和第一次)

    在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.InternalGetId(对象obj,布尔赋值UniqueIDToValueType,类型类型,布尔值&isNew)

    在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteString(NameInfo memberNameInfo,NameInfo typeNameInfo,Object stringObject)

    在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteKnownValueClass(NameInfo memberNameInfo,NameInfo typeNameInfo,对象数据)

    在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMembers(名称信息memberNameInfo,名称信息memberTypeNameInfo,对象成员数据,WriteObjectInfo objectInfo,名称信息typeNameInfo,WriteObjectInfo memberObjectInfo)

    在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMemberSetup(WriteObjectInfo objectInfo、NameInfo memberNameInfo、NameInfo typeNameInfo、String memberName、Type memberType、Object memberData、WriteObjectInfo memberObjectInfo)

    在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo,NameInfo memberNameInfo,NameInfo typeNameInfo,String[]MemberName,Type[]memberTypes,Object[]memberData,WriteObjectInfo[]MemberObjectInfo)

    在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo,NameInfo memberNameInfo,NameInfo typeNameInfo)

    在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serializate(对象图,头[]inHeaders,\uu BinaryWriter serWriter,布尔fCheck)

    在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serializate(流序列化流,对象图,头[]头,布尔fCheck)

    在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serializate(流序列化流,对象图)


    使用流序列化每个对象。请参见一个示例: 注意:这只是一个模板,不是完整的代码。我只是想给你一个想法

    private void SerializeObjects(List<foo> foos, Stream stream)
    {
        foreach (var f in foos)
        {
            stream.Write(f);
        }
    }
    
    private void DeserializeObjects(List<foo> foos, Stream stream)
    {
        foo f = stream.ReadFoo();
        while (f != null)
        {
            foos.Add(f);
            f = stream.ReadFoo();
        }
    }
    
    private void序列化对象(列出foo、Stream)
    {
    foreach(foos中的var f)
    {
    流写入(f);
    }
    }
    私有void反序列化对象(列表foo、流)
    {
    foo f=stream.ReadFoo();
    while(f!=null)
    {
    添加(f);
    f=stream.ReadFoo();
    }
    }
    
    请参阅下面的帖子:谢谢,尽管它看起来位于正确的区域。我将尝试一次处理每个事件1(或x)的序列化操作,看看是否可以避免BinaryFormatter graph Serializer出现此问题。我刚刚切换到protobuf net,我的内存问题消失了!诚然,我最终得到了一个用于1m事件的400MB文件,但我可以将其写入一个临时文件,然后在执行初始反序列化后将其gzip到8MB。请参阅本文,我让序列化对象正常工作,但是stream.ReadFoo()是什么?我必须自己写一个方法?ReadFoo只是一个例子,因为你可以从很多方面阅读。只需使用流中需要的读取。请参阅stream类。我想说,MemoryStream是您必须序列化和反序列化的内容
    private void SerializeObjects(List<foo> foos, Stream stream)
    {
        foreach (var f in foos)
        {
            stream.Write(f);
        }
    }
    
    private void DeserializeObjects(List<foo> foos, Stream stream)
    {
        foo f = stream.ReadFoo();
        while (f != null)
        {
            foos.Add(f);
            f = stream.ReadFoo();
        }
    }