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

本文关键字:对象 列表 包含大 序列化 我应该 | 更新日期: 2023-09-27 18:06:43

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

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

我正在尝试使用格式化程序将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. 有更好的方法吗

以下是完整的例外:

无法保存文件:System.OutOfMemoryException:引发了类型为"System.OutOfMemory Exception"的异常。

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

在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteString(名称信息成员名称信息,名称信息类型名称信息,对象字符串对象(

在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteKnownValueClass(名称信息成员名称信息,名称信息类型名称信息,对象数据(

在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMembers(NameInfo memberNameInfo、NameInfo member typeNameInfo、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(

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

在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(对象图,Header[]inHeaders,__BinaryWriter serWriter,布尔fCheck(

在System.Runtime.Serialization.Formatters.BinaryFormatter.Serialize(流序列化流,对象图,Header[]标头,布尔fCheck(

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

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

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

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