【问题标题】:Will XmlSerializer ever create empty documentsXmlSerializer 是否会创建空文档
【发布时间】:2010-12-07 18:49:42
【问题描述】:

好的,以下代码我已经在生产环境中使用了一年多,没有任何变化。它一直运作良好。在过去的一个月内,少数机器报告说 xml 文档完全是空的。它们甚至不包含 xml 标头。我不能复制突然变空的文件,我也不能建议一种方法让它发生。我希望有人遇到过他们解决的类似问题。

大多数使用此代码的机器已经使用了大约一年,如果不是更多的话。以前的空文件中包含数据和列表。这些文件不会同时序列化。程序退出前一个接一个的保存/序列化。

我的问题: 下面的代码是否可以创建一个空文件? 还有什么会导致他们突然空虚? 在过去的一个月里,还有其他人遇到过 XML-serializer 的问题吗? (这个问题仅在过去一个月内发生在已经稳定 3 个月以上的版本上。)

如果您有任何问题或我遗漏了什么,请询问。我序列化的类型也很多种......所以如果你能想象它,我可能会有类似的东西被序列化。

 public class BackEnd<T> {
 public string FileSaveLocation = "this gets set on startup";
 public bool DisabledSerial;
 public virtual void BeforeDeserialize() { }
 public virtual void BeforeSerialize() { }
 public virtual void OnSuccessfulSerialize() { }
 protected virtual void OnSuccessfulDeserialize(ListBackEnd<T> tmpList) { }
 protected virtual void OnDeserialize(ListBackEnd<T> tmpList) { }

 public virtual void serialize()
    {
        if (DisabledSerial)
            return;
        try
        {
            BeforeSerialize();

            using (TextWriter textWrite = new StreamWriter(FileSaveLocation))
            {
                (new XmlSerializer(this.GetType())).Serialize(textWrite, this);
                Debug.WriteLine(" [S]");
                textWrite.Close();
            }
            OnSuccessfulSerialize();
        }
        catch (Exception e)
        {
            Static.Backup.XmlFile(FileSaveLocation);
            Log.ErrorCatch(e,
                "xml",
                "serialize - " + typeof(T) + " - " + (new FileInfo(FileSaveLocation)).Name);
        }

    }

    public virtual object deserialize(TextReader reader)
    {
        if (this.DisabledSerial)
            return false;


        ListBackEnd<T> tmp = null;


        this.BeforeDeserialize();

        if (reader == null && !File.Exists(this.FileSaveLocation))
        {
            Log.Write(Family.Error,
                "xml",
                "deserialize - " + this.GetType() + " - file not found. " + (new FileInfo(FileSaveLocation)).Name);
        }
        else
        {
            try
            {
                using (TextReader textRead = ((reader == null) ? new StreamReader(this.FileSaveLocation) : reader))
                {
                    tmp = (ListBackEnd<T>)this.get_serializer().Deserialize(textRead);
                    Debug.WriteLine(" [D]");
                    textRead.Close();
                }
                OnSuccessfulDeserialize(tmp);

                if (tmp != null)
                {
                    this._Items = tmp._Items;
                    this.AutoIncrementSeed = tmp.AutoIncrementSeed;
                    if (this._Items.Count > this.AutoIncrementSeed && this._Items[0] is ItemStorage)
                        this.AutoIncrementSeed = this._Items.Max(item => (item as ItemStorage).Key);
                }
            }
            catch (Exception e)
            {
                // this only copies the file
                Static.Backup.XmlFile(FileSaveLocation);
                // this only logs the exception
                Log.ErrorCatch(e,
                    "xml",
                    "deserialize - " + typeof(T) + " - " + (new FileInfo(FileSaveLocation)).Name);
            }
        }
        //{ Log.ErrorCatch(e, "xml", "deserialize" + this.GetType() + " - " + this.FileSaveLocation); }

        OnDeserialize(tmp);

        tmp = null;

        return (_Items.Count > 0);
    }
}

【问题讨论】:

    标签: c# xmlserializer


    【解决方案1】:

    我们在 $WORK 多次遇到过这个问题,症状是一个大小正确但填充了零字节的空文件。

    我们找到的解决方案是在 FileStream 上设置 WriteThrough 值:

    using (Stream file = new FileStream(settingTemp, FileMode.Create,
                                       FileAccess.Write, FileShare.None,
                                       0x1000, FileOptions.WriteThrough))
    {
       using (StreamWriter sw = new StreamWriter(file))
       {
          ...
       }
    }
    

    【讨论】:

    • 仅供参考:这将禁用写入缓存(如在 Windows 中使用)并直接提交到文件(可能仍需要刷新/自动刷新?)。 0x1000 是 4096 的默认缓冲区大小。
    • 我面临着同样的问题。你知道根本原因是什么吗?
    • “根本原因” - 人们在没有正确关闭 Windows 的情况下关闭计算机。
    【解决方案2】:

    我认为会发生这种情况的唯一原因是这一行:

    (new XmlSerializer(this.GetType())).Serialize(textWrite, this);
    

    抛出一个异常,并且文本编写器被创建和处理,而没有任何内容写入它。我会查看您的日志是否有错误。

    做什么

    Static.Backup.XmlFile(FileSaveLocation);
    

    做吗?

    【讨论】:

    • 我会接受的。我从来没有想过 using 语句中的异常会像那样清空文件。其他事情进展顺利。非常感谢达斯汀。
    • 它只是复制文件。如果由于某种原因我没有正确添加可选字段属性,它会保存原始属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多