C#,Windows 7:如何可靠地检查进程是否仍在写入文件
本文关键字:是否 进程 文件 检查 Windows 何可 | 更新日期: 2023-09-27 18:26:49
我有一个C#实用程序,它需要在另一个进程释放特定文件后立即执行一些操作,即该进程停止写入该文件。我正在使用下面的代码,但它在Windows7系统上的表现不一致。
private static bool FileWritten(string filename)
{
try
{
using (FileStream inputStream = File.Open(filename, FileMode.Open,
FileAccess.Read,
FileShare.None))
{
return true;
}
}
catch (IOException e)
{
return false;
}
}
有时它会返回false,即使文件似乎已经发布。我在while(true)循环中调用FileWritten(),只要它返回false,就会一直检查调用FileWriten()的情况,然后在最长时间后退出。调试这一点很困难,因为它在调试器下似乎可以很好地工作(即,一旦文件真正发布,它就会返回true),但当我直接启动代码时,它就不起作用了。此外,即使添加调试打印似乎也会影响其行为。
是否有更可靠的方法来检查文件是否已写入并发布,这将在Win 7上运行,最好也在Win XP上运行?
这个问题没有完美的解决方案。
即使你的代码在Windows7上运行良好,仍然会有竞争条件。
假设FileWritten
在某个时间点返回false
。您的代码假定该文件不再被锁定并继续执行。。。但该文件可能会在下一毫秒再次锁定,下次您尝试访问该文件时,它将抛出异常。。。
难道你不能试着访问你的文件,如果你不能访问它,就抓住异常吗?然后你可以等待一段时间,然后再试一次。它将比试图返回布尔值的函数更干净,该布尔值指示文件是否被进程使用。
您可以使用FileSystemWatcher来侦听文件上的事件。一些选项将允许您查看文件是否已更改。每当收到文件更改的通知时,您可以使用爆米花效果(重置计时器)使线程睡眠一定时间。然后执行你的代码(但实际上让它在你有锁的时候在True路径中完成你的工作)。如果文件仍然被锁定,则会出现错误,请多睡一会儿等待事件。
除了让其他进程在完成后重命名/复制原始文件到新位置之外,没有通用的API可以在其他进程删除文件后立即为您提供文件锁定。