我应该如何序列化包含大量对象的对象?

时间:2015-08-07 03:31:42

标签: c# .net serialization clr

我使用的是c#和.net 4.5。

我有一个SomeData类,它包含一个成员_SomeEvents,它是一个Dictionary。 SomeData类还包含一堆信息,例如生成数据的时间,生成数据的用户等。

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

IFormatter formatter = new BinaryFormatter();
Stream stream;
stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, _myObject);
stream.Close();

我读过的其他帖子表明,内存不足问题是由于无法找到足够大的连续可用内存区域来生成要写入磁盘的数据。我还读到这是错误的'序列化的方式 - 我的假设是,如果我正确地执行它,CLR会在数据发送时写入数据,而不是在保存之前尝试在内存中准备全部数据。也就是说 - 我确实看到在序列化操作失败之前创建了一个大文件,暗示它正在写入。

我试过更改Serialize操作来编写Dictionary对象本身而不是包含Dictionary的对象 - 同样的问题,我得到了内存异常。

问题:

  1. 为什么Serialize会遇到这个内存问题 - 即使我给它一个Dictionary对象来序列化 - 因为它确实会写入它的内容?
  2. 有更好的方法吗?!!
  3. 以下是完整的例外情况:

      

    无法保存文件:System.OutOfMemoryException:类型' System.OutOfMemoryException'的异常被扔了。

         

    在System.Runtime.Serialization.ObjectIDGenerator.Rehash()

         

    at System.Runtime.Serialization.ObjectIDGenerator.GetId(Object obj,Boolean& firstTime)

         

    at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.InternalGetId(Object obj,Boolean assignUniqueIdToValueType,Type type,Boolean& isNew)

         

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

         

    at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteKnownValueClass(NameInfo memberNameInfo,NameInfo typeNameInfo,Object data)

         

    在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMembers(NameInfo memberNameInfo,NameInfo memberTypeNameInfo,Object memberData,WriteObjectInfo objectInfo,NameInfo typeNameInfo,WriteObjectInfo memberObjectInfo)

         

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

         

    at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo,NameInfo memberNameInfo,NameInfo typeNameInfo,String [] memberNames,Type [] memberTypes,Object [] memberData,WriteObjectInfo [] memberObjectInfos)

         

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

         

    at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph,Header [] inHeaders,__BinaryWriter serWriter,Boolean fCheck)

         

    在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream,Object graph,Header [] headers,Boolean fCheck)

         

    在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream,Object graph)

1 个答案:

答案 0 :(得分:0)

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

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();
    }
}