如何在 C# 中检查 File.Delete() 是不是会在不尝试的情况下成功?
Posted
技术标签:
【中文标题】如何在 C# 中检查 File.Delete() 是不是会在不尝试的情况下成功?【英文标题】:How do I check whether File.Delete() will succeed without trying it, in C#?如何在 C# 中检查 File.Delete() 是否会在不尝试的情况下成功? 【发布时间】:2010-11-29 11:19:48 【问题描述】:在 C# 中,System.IO.File.Delete(filePath) 将删除指定文件或引发异常。如果当前用户没有删除文件的权限,则会引发 UnauthorizedAccessException。
有什么方法可以让我提前判断删除是否可能引发 UnauthorizedAccessException(即查询 ACL 以查看当前线程的身份是否有权删除指定文件?)
我基本上想做:
if (FileIsDeletableByCurrentUser(filePath))
/* remove supporting database records, etc. here */
File.Delete(filePath);
但我不知道如何实现 FileIsDeletableByCurrentUser()。
【问题讨论】:
处理竞争条件非常困难。如果在您评估FileIsDeletableByCurrentUser
时文件“可以”删除,但在此之后,其他进程锁定了文件怎么办?
如果文件被其他进程(例如 IIS 或 office)打开,您也无法删除该文件。这可能是相同的例外,但您无法仅通过查看权限来判断
您确定仅对特定异常使用 try/catch 不是处理此问题的正确方法吗?看来您正在尝试在这里重新发明***。
带有最终解决方案的示例代码?
如果您想自己编写代码检查权限,此 Microsoft 文档链接一定会有所帮助:docs.microsoft.com/en-us/dotnet/api/…
【参考方案1】:
实现FileIsDeletableByCurrentUser
的问题在于不可能这样做。原因是文件系统是一个不断变化的项目。
在您对文件系统进行的任何检查和下一次操作之间,任何数量的事件都可能发生并且将会发生。包括...
文件的权限可能会改变 可以删除文件 文件可能被其他用户/进程锁定 可以移除文件所在的 USB 密钥你能写出的最好的函数应该命名为FileWasDeletableByCurrentUser
。
【讨论】:
投了赞成票,因为您提出的函数名称既幽默又富有洞察力。 愚蠢的推理......“是”会很好,因为您正在那个确切点检查权限。否则,我们将使用名为“ReadOldData”的文件 api 函数,以防数据在读取和实际使用之间发生变化。【参考方案2】:如上所述。 查找文件权限并与运行应用程序的用户进行比较。
你也可以一直使用这种方法
bool deletemyfile()
try
...delete my file
return true;
catch
return false;
如果它返回 false,那么如果它返回 true,那么你知道它失败了......它工作并且文件消失了。不知道你到底在追求什么,但这是我能想到的最好的了
【讨论】:
【参考方案3】:似乎按以下顺序做事情会更容易:
-
获取文件所需的任何信息,以便执行其他部分(删除数据库数据等)
尝试删除文件
如果您成功删除了文件,则进行其余的“清理”工作。如果没有成功删除,返回/处理异常等。
【讨论】:
【参考方案4】:您应该获得该文件的访问控制列表 (ACL)。
但这并不一定意味着您可以实际删除它,因为仍然可以设置只读标志或其他程序已锁定该文件。
【讨论】:
【参考方案5】:严格来说,UnauthorizedAccessException 意味着路径是一个目录,所以你可以使用 System.IO.Path.GetFileName(path) 类型的命令并捕获参数异常。
但如果您想要更全面的解决方案,请使用 Dale Halliwell 提到的 System.IO.File.GetAccessControl
【讨论】:
【参考方案6】:当然,您可以使用 System.IO 来检查 ReadOnly 标志,并且可能还结合当前用户检查文件上的 ACL 安全性,但就像 Mehrdad 在他的评论中所写的那样,它永远不会在所有情况下都是完全证明的。因此,您需要始终对异常情况进行异常处理(即使它只是 a top-level catch-all,它会记录/显示“意外问题”并终止您的应用程序)。
【讨论】:
【参考方案7】:您是否尝试过 System.IO.File.GetAccessControl(filename) 它应该返回一个 FileSecurity,其中包含有关该文件权限的信息。
【讨论】:
以上是关于如何在 C# 中检查 File.Delete() 是不是会在不尝试的情况下成功?的主要内容,如果未能解决你的问题,请参考以下文章
C# ,winform,如何清空或者删除一个文本文档(.txt 文件),路径已知