【问题标题】:Reading an XML file while it is being written to在写入 XML 文件时读取它
【发布时间】:2016-11-09 17:17:48
【问题描述】:

我有一个编译 XML 文件的长时间运行的 REST API 方法。用户发出请求以启动此编译,创建基本文件,然后为用户提供一个唯一 ID,用于查询进度。

当被调用时,进度读取方法以只读访问打开文件,实例化一个XDocument对象并计算其中的元素数量。

填充 XML 文件的代码被访问

using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
{
    var xmlDoc = XDocument.Load(fs);

    foreach (...)
    {
        // add the element to xmlDoc

        xmlDoc.Save(filePath);
    }
}

以及读取文件以计算元素数量的代码

using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    var xmlDoc = XDocument.Load(fs);

    // count elements
}

但是,在 populating 方法中,xmlDoc.Save(filePath);

会引发异常

该进程无法访问文件“...”,因为它正被另一个进程使用。

据我了解,使用 FileShare.Read 打开 FileStream 允许另一个进程以只读访问权限打开文件(我相信这种情况正在发生),同样在读取/计数方法中使用 FileShare.ReadWrite 将允许填充进程以使用写访问权限打开文件。

为什么上面的代码不允许两个进程都按照我的预期去做?

【问题讨论】:

    标签: c# .net xml read-write file-access


    【解决方案1】:

    当你打电话时

    xmlDoc.Save(filePath)
    

    您传递文件名,因此XmlDocument 不会使用您为写入而打开的fs 流。相反,它会在内部打开另一个流,这当然会失败,因为您已经打开了一个流进行写入。

    而是寻找到流的开头,然后调用

    xmlDoc.Save(fs);
    

    您也可以在保存之前将流长度设置为零(以截断旧内容),但不能完全确定是否有必要。

    【讨论】:

    • 您能否解释一下“您还可以在保存之前将流长度设置为零(以截断旧内容)”的建议背后的原因?在保存删除流的内容之前不会将流 length 设置为 0 吗?或者你的意思是我应该将长度设置为当前位置?
    • 您首先打开一个包含现有内容的流并将该内容读入 XDocument (XDocument.Load)。假设文件是​​ 1000 字节。在保存之前,流的长度为 1000,位置为 1000。您寻求位置 0 并保存。现在假设新文档的长度为 900。如果 XDocument.Save 没有将流长度本身设置为 900,您最终可能会拥有 900 字节的新文档 + 100 字节的先前文档,总共 1000,这不是您想要的想。由于我不确定 XDocument.Save 在内部是如何工作的,因此我建议在保存之前截断流。
    • 好的,需要做2点:(1)写入文件的内容只会增长;打开时,FileStream 永远不会比以前更短。 (2) 在实现这一点时,我遇到了异常“尝试在流开始之前移动位置”。这发生在看似随机的时间 - 有时在第一次查询读取期间,其他时间则更晚。
    • 1.如果按顺序向文件中添加元素,则不需要使用 XDocument,因为保存它会覆盖整个文件,而不是在末尾添加内容。好吧,你可以使用 XDocument,只是效率不高。相反,您可以使用一些流式 xml api(XmlWriter 等)。 2. 它究竟在哪一行抛出了这样的异常,在哪个方法(读或写)?
    • 不客气。读取该计数文件时要小心 - 在非常罕见的情况下,当写入同时发生时,它仍然可能会抛出“进程无法访问文件......”错误。所以你必须在一个循环中多次尝试。
    猜你喜欢
    • 1970-01-01
    • 2017-11-07
    • 1970-01-01
    • 2012-03-04
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多