我有一个C#实用程序需要在另一个进程释放特定文件时执行某些操作,即该进程停止写入文件。我正在使用下面的代码,但它在Windows 7系统上表现不一致。
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,就会一直检查调用FileWritten(),然后在一段时间后退出。调试这很困难,因为它似乎在调试器下工作正常(即,一旦文件实际释放它就返回true)但是当我直接启动我的代码时它不起作用。此外,即使添加调试打印也似乎会影响其行为。
是否有更可靠的方法来检查文件是否已被写入和发布,哪种文件可以使用Win 7,最好也适用于Win XP?
答案 0 :(得分:1)
这个问题没有完美的解决方案。
即使你的代码在Windows 7上工作正常,仍然会有竞争条件。
想象一下,FileWritten
会在某个时间点返回false
。您的代码假定文件不再被锁定并继续执行...但文件可能会在下一毫秒再次被锁定,下次您尝试访问该文件时它会抛出异常......
您是否只能尝试访问您的文件,如果您无法访问它,请捕获异常?然后你可以等待一段时间然后再试一次。它会比尝试返回一个布尔值的函数更清晰IMO,该布尔值指示文件是否被进程使用。
答案 1 :(得分:0)
您可以使用FileSystemWatcher侦听文件中的事件。 few of the options将允许您查看文件是否已更改。每当收到文件更改通知时,您都可以使用爆米花效果(重置计时器)让您的线程休眠一段时间。然后执行你的代码(但实际上让它在你拥有锁的时候在True路径中完成你的工作)。如果文件仍然被锁定,你将会变得虚假,等待更多的事情等待事件。
除了让其他进程在完成时将原始文件重命名/复制到新位置之外,没有通用的API会在另一个进程丢弃之后立即为您提供文件锁定。 (我知道)。