C#,Windows 7:如何可靠地检查进程是否仍在写入文件?

时间:2012-03-06 16:38:18

标签: c# file windows-7

我有一个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?

2 个答案:

答案 0 :(得分:1)

这个问题没有完美的解决方案。

即使你的代码在Windows 7上工作正常,仍然会有竞争条件。

想象一下,FileWritten会在某个时间点返回false。您的代码假定文件不再被锁定并继续执行...但文件可能会在下一毫秒再次被锁定,下次您尝试访问该文件时它会抛出异常......

您是否只能尝试访问您的文件,如果您无法访问它,请捕获异常?然后你可以等待一段时间然后再试一次。它会比尝试返回一个布尔值的函数更清晰IMO,该布尔值指示文件是否被进程使用。

答案 1 :(得分:0)

您可以使用FileSystemWatcher侦听文件中的事件。 few of the options将允许您查看文件是否已更改。每当收到文件更改通知时,您都可以使用爆米花效果(重置计时器)让您的线程休眠一段时间。然后执行你的代码(但实际上让它在你拥有锁的时候在True路径中完成你的工作)。如果文件仍然被锁定,你将会变得虚假,等待更多的事情等待事件。

除了让其他进程在完成时将原始文件重命名/复制到新位置之外,没有通用的API会在另一个进程丢弃之后立即为您提供文件锁定。 (我知道)。