【问题标题】:DataContractSerializer writes corrupted dataDataContractSerializer 写入损坏的数据
【发布时间】:2017-10-13 16:03:27
【问题描述】:

我正在使用以下代码在磁盘上存储一些对象:

    public static void Save<T>(T obj, string filename)
    {
        using (var output = System.IO.File.OpenWrite(filename))
        using (var writer = new System.Xml.XmlTextWriter(output, System.Text.Encoding.UTF8)
        {
            Formatting = System.Xml.Formatting.Indented
        })
        {
            var serializer = new System.Runtime.Serialization.DataContractSerializer(typeof(T));
            serializer.WriteObject(writer, obj);
        }
    }

有时保存的文件会损坏,这意味着它包含一些随机的附加垃圾数据,这些数据会阻止进一步的反序列化,例如:

<Parameters xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/MyApp">
    ...
</Parameters>eters>

这里最后 6 个字符来自标记的一些剩余部分,防止反序列化此文件。为什么会发生,我该如何解决?

会不会是在Form.Closing事件处理器中调用Save方法引起的?

【问题讨论】:

  • 有点像你在重复写入同一个文件,并且在你再次写入之前文件没有被截断。如果您上次写给它的内容比新的长六个字符并以“&lt;/Parameters&gt;”结尾 - 就是这样。 System.IO.File.Delete(filename); 作为方法中的第一行应该清楚这一点,我想。不确定当文件不存在时是否会抛出。
  • @EdPlunkett 当然!来自 OpenWrite 的文档:“打开现有文件或创建新文件以进行写入。”非常感谢!
  • 使用new System.IO.FileStream(filename, FileMode.Create) 而不是OpenWrite
  • @AlexanderPetrov 你首先得到了正确的答案——发布它,我会删除我的

标签: c# .net xml serialization datacontractserializer


【解决方案1】:

这是documented behavior with OpenWrite()

如果文件路径已存在文件,OpenWrite 方法将打开一个文件,如果文件不存在,则创建一个新文件。对于现有文件,它不会将新文本附加到现有文本。相反,它会用新字符覆盖现有字符。 如果您覆盖较长的字符串(如“这是对 OpenWrite 方法的测试”)用较短的字符串(如“第二次运行”),该文件将包含混合字符串(“OpenWrite 方法的第二次运行测试”)。

所以你需要在写入之前明确截断文件,或者如果它存在就删除它。

Alexander Petrov 观察到 new System.IO.FileStream(filename, FileMode.Create) 在这种情况下是 OpenWrite() 的正确替代品。

【讨论】:

    猜你喜欢
    • 2017-09-14
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 2019-01-09
    • 2011-02-12
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    相关资源
    最近更新 更多