1. 程式人生 > >記錄一次錯誤處理 (xml序列化和反序列化相關)

記錄一次錯誤處理 (xml序列化和反序列化相關)

vfl last events all 長度 pat vid pac ria

XML序列化後,反序列化時出現錯誤

報錯現象

System.InvalidOperationException: XML 文檔(40, 11)中有錯誤。 ---> System.Xml.XmlException: 根級別上的數據無效。 第 40 行,位置 11。
   在 System.Xml.XmlTextReaderImpl.Throw(Exception e)
   在 System.Xml.XmlTextReaderImpl.ParseRootLevelWhitespace()
   在 System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   在 System.Xml.XmlReader.ReadEndElement()
   在 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderConfigs.Read3_Configs(Boolean isNullable, Boolean checkType)
   在 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderConfigs.Read4_Configs()
   --- 內部異常堆棧跟蹤的結尾 ---
   在 System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   在 System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
   在 DetectSys.Configs.LoadConfig() 位置 E:\DefctFramework\code\submitDS\DetectSystem\DetectSys.BLL\Config.cs:行號 55

報錯時,xml文件

查看了一下序列化的文件,在文件最後總是會多出一些垃圾字符導致反序列化錯誤
<?xml version="1.0"?>
<Configs xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Settings>
    <Setter Key="AppTitle" Value="三維可視化" />
    <Setter Key="WeatherCityName" Value="達州" />
<Setter Key="UavFlyCenterPoint" Value="107.204756400529,31.1305284689069,160.0" /> <Setter Key="SqlDbString" Value="Server=127.0.0.1;uid=root;Password=root;Database=d3videofusion" /> <Setter Key="IGetWeatherImpl" Value="WeatherPlugins.Impl.LocalWheather,WeatherPlugins.dll" /> <
Setter Key="autoBallonLayers" Value="tmpLayer\建築信息.lgd;tmpLayer\建築信息2.lgd" /> <Setter Key="GlaFile" Value="Gla\qingdao.gla" /> <Setter Key="GlaFile2" Value="Gla\shiyan2.gla" /> <Setter Key="region1" Value="tmpLayer\1片區.lgd;tmpLayer\pianqu.lgd" /> <Setter Key="region2" Value="tmpLayer\2pianqu.lgd" /> <Setter Key="region3" Value="tmpLayer\3pianqu.lgd" /> <Setter Key="region4" Value="tmpLayer\4pianqu.lgd" /> <Setter Key="region5" Value="tmpLayer\5pianqu.lgd" /> <Setter Key="region6" Value="tmpLayer\6pianqu.lgd" /> <Setter Key="region7" Value="tmpLayer\7pianqu.lgd" /> <Setter Key="region8" Value="tmpLayer\8pianqu.lgd" /> <Setter Key="region9" Value="tmpLayer\9pianqu.lgd" /> <Setter Key="region10" Value="tmpLayer\10pianqu.lgd" /> <Setter Key="region11" Value="tmpLayer\11pianqu.lgd" /> <Setter Key="region12" Value="tmpLayer\12pianqu.lgd" /> <Setter Key="LastSelectedDir" Value="E:\DefctFramework\數據\cout8" /> </Settings> <Catalogs> <Catalog Key="PATH_IMAGE_ICON_LABEL" Value="Resource\images\IconLabel" /> <Catalog Key="PATH_FengKongQu" Value="tmpLayer\封控區.lgd" /> <Catalog Key="PATH_HeXinQu" Value="tmpLayer\核心區.lgd" /> <Catalog Key="PATH_JingJieQu" Value="tmpLayer\警戒區.lgd" /> <Catalog Key="PATH_IMAGE" Value="resource\images" /> <Catalog Key="PATH_FRAME" Value="resource\frame" /> <Catalog Key="PATH_THREEDLL" Value="ThreeDll" /> <Catalog Key="PATH_JingJieQu" Value="tmpLayer\警戒區.lgd" /> <Catalog Key="PATH_IMAGE" Value="resource\images" /> <Catalog Key="PATH_FRAME" Value="resource\frame" /> <Catalog Key="PATH_THREEDLL" Value="ThreeDll" /> <Catalog Key="key" Value="value" /> </Catalogs> </Configs>Configs>

報錯的直接原因是xml文件後面多了

 Configs>
這種現象我稱之為 拖尾現象

註意,多出的垃圾字符是不是隨意的,是有規律的。

分析問題

但是為什麽會多呢

先檢查序列化代碼。代碼如下

public void Save()
        {
            if (config != null)
            {
                if (!File.Exists(saveFile))
                {
                    File.Create(saveFile).Close();
                }
                XmlSerializer serializer = new XmlSerializer(typeof(Configs));
                using (FileStream stream = new FileStream(saveFile, FileMode.Open))
                {
                    serializer.Serialize(stream, config);
                }
            }
        }

經過分析,問題就出在文件的打開方式上。

FileMode.Open方式,會覆蓋原始文件。如果新的對象長度小於原始對象長度,就會出現拖尾現象。

解決問題

把FileStream打開方式改為Truncate,問題解決

public void Save()
        {
            if (config != null)
            {
                if (!File.Exists(saveFile))
                {
                    File.Create(saveFile).Close();
                }
                XmlSerializer serializer = new XmlSerializer(typeof(Configs));
                using (FileStream stream = new FileStream(saveFile, FileMode.Truncate))
                {
                    serializer.Serialize(stream, config);
                }
            }
        }

tag

記錄一次錯誤處理 (xml序列化和反序列化相關)