【问题标题】:XMLSerializer destroys parts of my file, why?XMLSerializer 破坏了我的部分文件,为什么?
【发布时间】:2016-09-23 02:25:50
【问题描述】:

我只是想反序列化,然后当我的对话框再次关闭时,在我的 WPF 应用程序中序列化一个 XML 文件。好吧,这在大多数情况下都有效,但有时,我文件中的某些字符完全丢失,它们只是消失了,使文件无法使用。我的代码:

    public static void WriteXML(MyModel MyModel)
    {            
        try
        {
            XmlSerializer serializer = new XmlSerializer(typeof(MyModel));
            using (var stream = new FileStream(fileName, FileMode.OpenOrCreate))
            {                    
                serializer.Serialize(stream, MyModel);
            }
        }
        catch (Exception e)
        {
            //...
        }
    }

我的 XML 文件前后看起来有点像:

<?xml version="1.0"?>
<MainModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Main>
    <SomeModel>
      <ID>1</ID>
      <Name>Af</Name>
      <SomeMonth>February</SomeMonth>
      <Level>10</Level>
      <Out>120</Out>
      <Hyb>true</Hyb>
    </SomeModel>
    <SomeModel>
      <ID>2</ID>
      <Name>Alm</Name>
      <SomeMonth>March</SomeMonth>
      <Level>5</Level>
      <Out>90</Out>
      <Hyb>true</Hyb>
    </SomeModel>
  </Main>  
</MainModel>

之后:

<?xml version="1.0"?>
<MainModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SomeModel>
      <ID>1</ID>
      <Name>Af</Name>
      <SomeMonth>February</SomeMonth>
      <Level>10</Level>
      <Out>120</Out>
      <Hyb>true</Hyb>
    </SomeModel>
    <SomeModel>
      <ID>2</ID>
      <Name>Alm</Name>
      <SomeMonth>March</SomeMonth>
      <Level>5</Level>
      <Out>90</Out>
      <Hyb>true</Hyb>
    </SomeModel>
  </Main>  
</MainModel>

【问题讨论】:

  • 你能转储MyModel类代码
  • 你确定你为之后粘贴了正确的 Xml 吗?关闭 没有匹配的开始标记。
  • 你知道过程中丢失了哪些字符吗?除了缺少的开始标签之外,我似乎在您发布之前和之后没有看到任何变化。会不会是您试图发送无效的 XML 字符?

标签: c# xml wpf xml-parsing xmlserializer


【解决方案1】:

目前还不清楚您的 XML 发生了什么(除了它是无效的)。你说它“有点像这样”——它肯定看起来会很有帮助。我会注意到你使用了错误的FileMode,所以我希望这是其中的一部分,我猜你的 actual XML 在第一行关闭了MainModel。

FileMode.OpenOrCreate 在the documentation 中有这些 cmets:

指定操作系统应该打开一个文件(如果存在);否则,应创建一个新文件。

这意味着如果您的文件已经存在(因为它确实存在),那么序列化程序只会写入它。文件在写入之前不会被截断,所以如果你正在写的内容比那里的短,你最终会得到一个损坏的输出,由你写的内容和之前的内容组成之前在那里。

你想要的是FileMode.Create,它有这些cmets:

指定操作系统应该创建一个新文件。如果文件已经存在,它将被覆盖。 ... FileMode.Create相当于请求如果文件不存在,使用CreateNew;否则,使用截断。

请注意,现有文件将被截断,这将避免此问题。

【讨论】:

    猜你喜欢
    • 2011-03-25
    • 2011-08-19
    • 2019-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多