替换文件内容,而不会中断读取器客户端的访问
本文关键字:读取 中断 客户端 访问 文件 替换 | 更新日期: 2023-09-27 17:57:20
有一个服务不断将新内容写入文件:
using (var stream = File.Create(FileName)) // overwrites the file
{
stream.Write(data, 0, data.Length);
}
该文件由多个阅读器(包括从该文件呈现其内容的 Web 应用程序)不断访问。我无法控制阅读器客户端代码。读者应始终可以访问该文件。更重要的是,他们应该看到整个内容,而不是写入文件的过程中的内容。
任何像这样的技术:
using (var stream = File.Create(FileName + ".tmp"))
{
stream.Write(data, 0, data.Length);
}
File.Delete(FileName);
File.Move(FileName + ".tmp", FileName);
可能导致网页上缺少内容(有一定概率)。该服务有时会抛出异常IOException
并显示消息"进程无法访问该文件,因为它正被另一个进程使用"。
问题是:如何在不中断读取器客户端访问的情况下不断替换文件内容?
在IIS中,您可以调整此模块(完全披露我编写的)以将同步注入读取请求。 您可以通过子类化 InterceptingHandler 并添加如下代码来执行此操作:
SychronizingHandler : InterceptingHandler
{
// ...
Semaphore mySemaphore;
protected override bool PreFilter(System.Web.HttpContext context)
{
context.RewritePath("myFilePath");
if( mySemaphore == null)
{
bool created;
mySemaphore = new Semaphore(100, 0, "semphoreName", out created);
}
if( mySemaphore != null)
{
mySemaphore.WaitOne();
}
reutrn true;
}
// note this function isn't in the base class
// you would need to add it and call it right after the call to
// innerHandler.ProcessRequest
protected override void PostFilter(System.Web.HttpContext context)
{
mySemaphore.Release();
return;
}
protected virtual void OnError(HttpContext context, Exception except)
{
mySemaphore.Release();
return base.OnError(context, except);
}
桌面应用程序有点棘手,因为它取决于应用程序的实现细节。 希望在这种情况下,您有某种方法来扩展它并添加同步。
正如 Fun 在评论中指出的那样,您还可以在预过滤器中进行有条件的重写,这样您就不会尝试访问正在写入的文件,这是一个非常好的主意。