如何在 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# 在后台线程中出现未经授权的错误

C# ,winform,如何清空或者删除一个文本文档(.txt 文件),路径已知

C# 在一行中继续 ForEach

如何实现异步 File.Delete/Create/Move?

C# 文件操作

C#删除文件