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

标签 c# .net serialization clr

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

我有一个类 SomeData,它包含一个成员 _SomeEvents,它是一个字典。 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 会在数据运行时写入数据,而不是在保存数据之前尝试将其全部准备在内存中。也就是说 - 我确实看到在序列化操作失败之前创建了一个大文件,这意味着它正在写入。

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

问题:

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

这是完整的异常:

Unable to save file: System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.

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

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

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

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

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

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

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

最佳答案

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

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

关于c# - 我应该如何序列化包含大量对象列表的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31869258/

相关文章:

C# 下载文件 - BADRESPONSE : Invalid or unexpected token

c# - DateTimeFormatInfo::AbbreviatedDayNames 的值是否在西类牙的 .Net 框架版本中发生过变化?

c# - 绳子神奇地自己切断

Javascript序列化窗口对象

java - Jackson 将字段序列化为不同的名称

c# - 用于在 C# 中选择的 SQL 查询生成器

.net - 需要说明在执行方法时如何对对象进行垃圾回收

c# - 当我的用户点击小键盘 Enter 键时,如何发送单个 Downkey 键?

c# - 如何使我的 Outlook 2007 加载项受信任

c# - 将类转换为字符串以通过电子邮件发送