文件系统是易变的。这意味着您不能相信一个操作的结果对于下一个操作仍然有效,即使它是下一行代码。你不能只说if (some file exists and I have permissions for it) open the file
, 你不能说 if (some file does not exist) create the file
.您的 if
的结果总是有可能条件将在代码的两个部分之间发生变化。这些操作是不同的:不是原子的。
更糟糕的是,问题的性质意味着,如果您想进行此检查,您很可能已经担心或意识到文件可能会发生您无法控制的事情。开发环境的性质使此事件在您的测试期间不太可能发生并且非常难以重现。因此,您不仅有错误,而且错误不会在测试时出现。
因此,在正常情况下,最好的做法是不要尝试检查文件或目录是否存在。相反,请将您的开发时间用于处理来自文件系统的异常。无论如何,您必须处理这些异常,因此这是对资源的更好利用。尽管异常很慢,但检查文件是否存在需要额外访问磁盘,并且磁盘访问要慢得多。我什至有一个好评 answer在另一个问题中达到这个效果。
但我有一些疑问。例如,在 .Net 中,如果确实总是如此,.Exists()
方法首先不会在 API 中。还要考虑您希望程序需要创建文件的场景。想到的第一个例子是桌面应用程序。该应用程序将一个默认的用户配置文件安装到它的主目录,并且当每个用户第一次启动该应用程序时,它会将这个文件复制到该用户的应用程序数据文件夹中。它希望该文件在第一次启动时不存在。
那么什么时候可以提前检查文件的存在(或其他属性,如大小和权限)?在第一次尝试时期待失败而不是成功是一个足够好的经验法则吗?
最佳答案
这取决于您的要求,但一种方法是尝试获取 独家打开文件句柄,带有某种重试机制。一旦有了那个句柄,另一个进程就很难(或不可能)删除(或移动)该文件。
我在 .NET 中使用了与以下类似的代码来获取独占文件句柄,我希望其他进程可能会在其中写入文件:
FileInfo fi = new FileInfo(fullFilePath);
int attempts = maxAttempts;
do
{
try
{
// Asking to open for reading with exclusive access...
fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.None);
}
// Ignore any errors...
catch {}
if (fs != null)
{
break;
}
else
{
Thread.Sleep(100);
}
}
while (--attempts > 0);
关于language-agnostic - 什么时候可以检查文件是否存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/673654/