我有一个长时间运行的编译XML文件的REST API方法。用户发出启动此编译的请求,创建基本文件,然后为用户提供用于查询进度的唯一ID。读取正在写入的XML文件
当被调用时,进度读取方法以只读方式打开文件,实例化一个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
}
然而,在填充方法引发的异常xmlDoc.Save(filePath);
进程无法访问文件'...',因为它正在被另一个进程使用。
正如我的理解是,与FileShare.Read
打开的FileStream允许另一个进程打开具有只读访问的文件(我相信这是发生),并同样在读/计数方法使用FileShare.ReadWrite
将允许填充进程使用写入访问来打开文件。
为什么上面的代码不允许这两个进程做我期望的?
您能解释一下这个建议背后的原因:“您也可以在保存之前将流长设置为零(截断旧内容)”?在保存删除流的内容之前,是不是将流_length_设置为0?或者也许你打算写我应该把长度设置到当前位置? – awj
您首先打开一个包含现有内容的流,并将该内容读入XDocument(XDocument.Load)。假设文件是1000字节。在保存之前,流的长度为1000,位置为1000.您试图将位置设置为0并保存。现在假设新文档的长度为900.如果XDocument.Save没有将流长度本身设置为900,那么最终可能会有900字节的新文档+以前的文档的100字节,总计为1000,而这不是您想。由于我不确定XDocument.Save如何在内部工作,所以我建议在保存之前截断流,可以肯定。 – Evk
好的,要做2点:(1)写入文件的内容只会增长;打开时,FileStream永远不会比以前更短。 (2)在实现这个时,我得到了一个例外:“试图在流开始之前移动位置”。这种情况发生在看似随机的时间 - 有时是在第一次查询时读取,其他时间在很多时候。 – awj