<分区>
我正在处理一个使用 .Net v3.5 和 C# (Visual Studio 2008) 的大型应用程序,该应用程序使用 BinaryFormatter
创建数据文件。
Stream stream = File.Open(filePath, FileMode.Create, FileAccess.Write, FileShare.None);
BinaryFormatter formatter = new BinaryFormatter(null, (new StreamingContext(StreamingContextStates.All, false)));
formatter.Serialize(stream, data);
stream.Flush();
stream.Close();
不幸的是,我经常从这个实现中得到 OutOfMemoryException
。我正在寻找某种可以快速过渡到的 BinaryFormatter
的替代品。
值得注意的是,此应用程序主要依赖于 ISerializable
,而不是 [Serializable]
属性来保留版本控制(某种)。此外,我们正在序列化的数据有多个指向同一个对象的变量。最后,我们还序列化列表和字典,使数据包含相当深的 ISerializable
层次结构。
因此,我更喜欢利用能够处理指向同一对象的重复指针的 ISerializable.GetObjectData
的替代方法。
编辑:在回复 dbc 时,你问了一个很好的问题。复制问题后,我得到的错误是:
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)
Quick Googling 告诉我,这是由于序列化了一个太大的对象。我很确定我没有存储任何二进制信息,如图像或音频,所以这让我觉得有点奇怪。我的猜测是列表可能太大而无法序列化。
顺便说一句,我使用相同的过程尝试了下面的代码,它们没有产生异常。
SerializationInfo info = new SerializationInfo(typeof(Data), new FormatterConverter());
StreamingContext context = new StreamingContext(StreamingContextStates.All, false);
data.GetObjectData(info, context);
foreach (SerializationEntry e in info)
{
Debug.WriteLine("Name: " + e.Name);
Debug.WriteLine("Type: " + e.ObjectType.ToString());
Debug.WriteLine("Value: " + e.Value.ToString());
}