2

我研究了几个问题,但我找到的答案都没有帮助。此函数的目标是修改 xml 文件。我读取原始文件并将旧的东西和新的东西写入新文件。所有这一切都完美无缺。当我完成并需要删除旧文件并移动新文件时,问题就出现了。

收到的错误是 jnv_config.xml 正在被另一个进程(阅读器文件)使用。

删除 Close 和/或 Dispose 并不能解决问题。

using (XmlReader reader = XmlReader.Create("jnv_config.xml"))
using (XmlWriter writer = XmlWriter.Create("jnv_temp.xml"))
{
    writer.WriteStartDocument();
    while (reader.Read())
    {
      // Read the file, write to the other file - this part works perfectly.
      // No filestreams nor anything else is created in here.
    }
    writer.WriteEndElement();
    writer.WriteEndDocument();
    reader.Close();
    writer.Close();
    reader.Dispose();
    writer.Dispose();
}
// Delete the old file and copy the new one
File.Delete("jnv_config.xml");
//File.Move("jnv_temp.xml", "jnv_config.xml");

我正在使用 VS2012 (NET 4.5)、C#、标准 Windows 窗体项目。

4

3 回答 3

4

你确定是这个XmlReader文件仍然打开吗?在执行此代码之前,您是否尝试过使用Process Explorer确认配置文件没有打开的文件句柄?

于 2013-02-06T00:12:08.420 回答
0

根据我的经验,许多 NTFS 文件处理函数(尤其是 DELETE)是略微异步的。尝试在重命名之前添加睡眠或等待至少 0.2 秒。


由于这不起作用,我建议将睡眠/等待放在前面,然后慢慢增加它直到它起作用。如果你达到了一些不合理的大时间跨度(比如 10 秒)并且它仍然不起作用,那么我认为你可以公平地得出结论,问题是XmlReader只要你留在这段代码中,你就没有被释放。

在这种情况下,您可能需要做一些事情来确保它被完全处置,比如强制 GC 运行。

于 2013-02-05T23:18:53.633 回答
0

Check if the file is ready before you delete it. If your working with large files perhaps call code via a loop for a couple of seconds.

private void IsFileOpen(FileInfo file)
{
    FileStream stream = null;
    try {
        stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    }
    catch (Exception ex) {

        if (ex is IOException && IsFileLocked(ex)) {
            // do something here, either close the file if you have a handle or as a last resort terminate the process - which could cause corruption and lose data
        }
    }
}

private static bool IsFileLocked(Exception exception)
{
    int errorCode = Marshal.GetHRForException(exception) & ((1 << 16) - 1);
    return errorCode == 32 || errorCode == 33;
}
于 2013-02-06T00:26:43.830 回答