【问题标题】:XmlSerializer is not serializing to a valid xmlXmlSerializer 未序列化为有效的 xml
【发布时间】:2013-06-18 11:27:45
【问题描述】:

请考虑以下代码:

public class Obj : IObj
{
    public string Prop1{get;set;}
    public string Prop2{get;set;}
    public string Prop3{get;set;}
}

public static void Persist(IObj obj, string fileFullName)
{
    try
    {
        Directory.CreateDirectory(Path.GetDirectoryName(fileFullName));

        var xmlSerializer = new XmlSerializer(obj.GetType());

        using (var fileStream = File.Open(fileFullName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
        {
            xmlSerializer.Serialize(fileStream, obj);
            fileStream.Close();
        }
    }
    catch (Exception e)
    {
       //log
    }
}

当第一次在 'Obj' 上调用 'Persist' 时,我在磁盘上得到了一个有效的 xml 文件,它看起来像这样:

<?xml version="1.0"?>
<Obj xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Prop1>value1</Prop1>
    <Prop2>value2</Prop2>
    <Prop2>value3</Prop3>
</Obj>

但是当在 'Obj' 上第二次调用 'Persist' 时(在将 'value1' 更改为 ' value',例如),一个额外的 '>' 符号会添加到文件的末尾,使其无效。

<?xml version="1.0"?>
<Obj xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Prop1>value</Prop1>
    <Prop2>value2</Prop2>
    <Prop2>value3</Prop3>
</Obj>>

我尝试调试它但没有发现任何异常,所以我猜它必须这样做 以我打开文件的方式。 任何解释它的帮助将不胜感激。

【问题讨论】:

    标签: c# xml-serialization xmlserializer


    【解决方案1】:

    如果文件存在,您将打开它并根据需要覆盖尽可能多的字节。如果这小于当前文件长度,那么您将在最后留下字符。尝试改用FileMode.Create

    【讨论】:

    • 打败了我 ;p 并且完全正确。引用MSDN(forCreate):“指定操作系统应该创建一个新文件,如果文件已经存在,就会被覆盖。这需要FileIOPermissionAccess.Write。System.IO.FileMode.Create相当于请求如果文件不存在,则使用 CreateNew;否则,使用 Truncate。"
    【解决方案2】:

    我怀疑您只会在后续 XML 小于之前的 XML 时看到这个 - 您需要设置 fileStream 的长度,例如:

    xmlSerializer.Serialize(fileStream, obj);
    if (fileStream.CanSeek)
    {
         fileStream.SetLength(fileStream.Position);
    }
    

    或者,在创建流时指定FileMode.Create

    【讨论】:

    • 这也可以解决问题,是的;最好使用Create 打开,但当您的代码交给 FileStream 并且不负责创建/打开文件时,这是一个很好的答案
    • 作为一种风格说明,我倾向于采用 Persist 方法,该方法采用流,重载采用文件 - 如果您想坚持使用 @987654327,以后会很方便@在单元测试中,例如...(这也是我检查CanSeek的原因)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    相关资源
    最近更新 更多