Jap*_*tar 2 .net c# serialization
我正在使用.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();
Run Code Online (Sandbox Code Playgroud)
不幸的是,我经常OutOfMemoryException从这个实现中获益.我正在寻找某种替代方案BinaryFormatter,我可以快速过渡到.
值得注意的是,这个应用程序主要依赖于ISerializable而不是[Serializable]属性来保留版本(各种类型).此外,我们序列化的数据有多个指向同一对象的变量.最后,我们还将Lists和Dictionaries序列化,使数据包含相当深的ISerializables 层次结构.
因此,我更喜欢利用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)
Run Code Online (Sandbox Code Playgroud)
快速谷歌搜索告诉我,这是由于序列化一个太大的对象.我很确定我没有存储任何二进制信息,如图像或音频,所以这让我觉得有点奇怪.我的猜测可能是列表太大而无法序列化.
顺便说一下,我使用相同的过程尝试了下面的代码,它们不会产生异常.
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());
}
Run Code Online (Sandbox Code Playgroud)
dbc*_*dbc 10
不抛出该特定异常,因为您正在序列化太大的对象.抛出它是因为您正在序列化具有如此多对象的对象图,以至于ObjectIDGenerator内部BinaryFormatter无法分配足够大的哈希表来为每个指针分配唯一ID.序列化ObjectIDGenerator程序用于为序列化的每个引用类生成运行时唯一ID,以便将对同一类实例的多个引用正确序列化为单个基于id的间接引用.您选择的任何图形序列化程序都需要执行此类操作.
您可以减少同时序列化的类实例数量,而不是采用一种非常繁琐的新图形序列化器技术吗?例如,您是否可以将对象图断开为断开的段,并将每个段顺序序列化为流?(关于如何执行此操作的一个教程是:将许多不同的对象序列化为单个文件.)或者您是否有一些包含多个小叶类的类,这些类永远不会被共享,并且可以替换为所有这些类的单个代理?
| 归档时间: |
|
| 查看次数: |
2294 次 |
| 最近记录: |