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

gf1*_*072 6 .net c# clr serialization

我正在使用c#和.net 4.5.

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

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

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

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

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

问题:

  1. 为什么Serialize会遇到这个内存问题 - 即使我给它一个Dictionary对象来序列化 - 当然它会写入它的内容吗?
  2. 有更好的方法吗?!!

这是完整的例外:

无法保存文件:System.OutOfMemoryException:抛出了类型'System.OutOfMemoryException'的异常.

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

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

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

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

在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)

Mar*_*sel 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();
    }
}
Run Code Online (Sandbox Code Playgroud)