什么可能导致XML文件填充空字符?

Kyl*_*ney 14 c# xml filesystems ntfs null-character

这是一个棘手的问题.我怀疑它需要一些文件系统的高级知识才能回答.

我有一个针对.NET framework 4.0的WPF应用程序"App1".它有一个Settings.settings文件,用于生成App1.exe.config存储默认设置的标准文件.当用户修改设置时,修改将进入AppData\Roaming\MyCompany\App1\X.X.0.0\user.config.这是所有标准的.NET行为.但是,有时,我们发现user.config客户机器上的文件不是应该的,导致应用程序崩溃.

问题看起来像这样:user.config如果用XML填充它应该是大小,但是它只是一堆NUL字符而不是XML.它的角色0一遍又一遍地重复着.我们没有关于导致此文件修改的内容的信息.

在此输入图像描述

如果我们只是删除,我们可以在客户的设备上修复该问题,user.config因为公共语言运行时只会生成一个新问题.他们将失去他们对设置所做的更改,但可以再次进行更改.

但是,我在另一个带有另一个XML文件的WPF应用程序"App2"中遇到了这个问题info.xml.这次是不同的,因为文件是由我自己的代码而不是CLR生成的.常见的主题是两个都是C#WPF应用程序,都是XML文件,在这两种情况下,我们完全无法在测试中重现问题.这可能与C#应用程序与XML文件或文件交互的方式有关吗?

我们不仅无法在当前的应用程序中重现该问题,而且我甚至无法通过编写有意产生错误的自定义代码来重现该问题.我找不到单个XML序列化错误或文件访问错误导致文件填充空值.那么可能会发生什么?

App1 user.config通过调用Upgrade()以及Save()获取和设置属性来访问.例如:

if (Settings.Default.UpgradeRequired)
{
    Settings.Default.Upgrade();
    Settings.Default.UpgradeRequired = false;
    Settings.Default.Save();
}
Run Code Online (Sandbox Code Playgroud)

info.xml通过序列化和反序列化XML来访问App2 :

public Info Deserialize(string xmlFile)
{
    if (File.Exists(xmlFile) == false)
    {
        return null;
    }

    XmlSerializer xmlReadSerializer = new XmlSerializer(typeof(Info));

    Info overview = null;

    using (StreamReader file = new StreamReader(xmlFile))
    {
        overview = (Info)xmlReadSerializer.Deserialize(file);
        file.Close();
    }

    return overview;
}

public void Serialize(Info infoObject, string fileName)
{
    XmlSerializer writer = new XmlSerializer(typeof(Info));

    using (StreamWriter fileWrite = new StreamWriter(fileName))
    {
        writer.Serialize(fileWrite, infoObject);
        fileWrite.Close();
    }
}
Run Code Online (Sandbox Code Playgroud)

我们在Windows 7和Windows 10上都遇到了这个问题.在研究这个问题时,我遇到了这个帖子,其中在Windows 8.1中遇到了相同的XML问题:保存的文件有时只包含NUL字符

有什么东西可以在我的代码中改变以防止这种情况,或者在.NET的行为中问题是否太深?

在我看来,有三种可能性:

  1. CLR正在将空字符写入XML文件.
  2. 文件的内存地址指针切换到另一个位置而不移动文件内容.
  3. 文件系统尝试将文件移动到另一个内存地址,文件内容被移动但指针不会更新.

我觉得2和3比1更可能.这就是为什么我说它可能需要先进的文件系统知识.

我非常感谢任何可能帮助我复制,修复或解决问题的信息.谢谢!

Cra*_*use 15

众所周知,如果断电就会发生这种情况。这发生在扩展文件(可以是新文件或现有文件)的缓存写入之后,此后不久就会发生断电。在这种情况下,当机器恢复时,文件有 3 种预期的可能状态:

1) 该文件根本不存在或具有其原始长度,就好像写入从未发生过一样。

2) 文件具有预期长度,就好像写入发生一样,但数据为零。

3) 文件具有预期的长度和写入的正确数据。

状态 2 就是您所描述的。发生这种情况是因为当您执行缓存写入时,NTFS 最初只是相应地扩展文件大小,但不影响 VDL(有效数据长度)。VDL 之外的数据总是作为零回读。您打算写入的数据位于文件缓存的内存中。它最终会被写入磁盘,通常在几秒钟内,然后 VDL 将在磁盘上前进以反映写入的数据。如果在写入数据之前或在 VDL 增加之前发生断电,您将最终处于状态 2。

这很容易复制,例如通过复制文件(复制引擎使用缓存写入),然后立即拔掉计算机上的电源插头。

  • 抱歉,我不知道我可以链接到描述这些交互的哪个来源。我是 Microsoft 的一名 NTFS 开发人员,所以我只是根据第一手知识描述它是如何工作的。 (2认同)