How do I check whether File.Delete() will succeed

2019-03-11 16:16发布

问题:

In C#, System.IO.File.Delete(filePath) will either delete the specified file, or raise an exception. If the current user doesn't have permission to delete the file, it'll raise an UnauthorizedAccessException.

Is there some way that I can tell ahead of time whether the delete is likely to throw an UnauthorizedAccessException or not (i.e. query the ACL to see whether the current thread's identity has permission to delete the specified file?)

I'm basically looking to do:

if (FileIsDeletableByCurrentUser(filePath)) {
    /* remove supporting database records, etc. here */
    File.Delete(filePath);
}

but I have no idea how to implement FileIsDeletableByCurrentUser().

回答1:

Take a look at this article - http://www.codeproject.com/KB/files/UserFileAccessRights.aspx



回答2:

The problem with implementing FileIsDeletableByCurrentUser is that it's not possible to do so. The reason is the file system is a constantly changing item.

In between any check you make to the file system and the next operation any number of events can and will happen. Including ...

  • Permissions on the file could change
  • The file could be deleted
  • The file could be locked by another user / process
  • The USB key the file is on could be removed

The best function you could write would most aptly be named FileWasDeletableByCurrentUser.



回答3:

Have you tried System.IO.File.GetAccessControl(filename) it should return a FileSecurity with information about the permissions for that file.



回答4:

Strictly speaking, an UnauthorizedAccessException means that the path is a directory, so you can use a System.IO.Path.GetFileName(path) type command and catch the argument exception.

But if you want a more holistic solution, use System.IO.File.GetAccessControl as mentioned by Dale Halliwell



回答5:

As stated above. Lookup the file permissions and compare with the user who is running the application.

You could always use this aproach as well

bool deletemyfile()  
{  
    try  
    {  
        ...delete my file  
        return true;  
    }  
    catch  
    {  
        return false;  
    }  
}

if it returns false you know it failed if it returns true then.. it worked and file is gone. Not sure what you're after exactly but this was the best I could think of



回答6:

Of course you can check ReadOnly flags using System.IO and probably ACL security on the file combined with the current user too, but like Mehrdad writes in his comment it would never be full-proof in all cases. So you would need exception handling for the exceptional case at all times (even if its just a top-level catch-all, that logs/shows an "unexpected problem" and kills your application).



回答7:

You should get the access control list (ACL) of that file.

But this doesn't necessarily mean you could actually delete it because the readonly flag could still be set or another program has locked the file.



回答8:

Seems like it would be easier to do things in the order of:

  1. Get whatever information you need about the file in order to do the other parts (delete database data, etc)
  2. Try to delete the file
  3. If you successfully delete the file, then carry out the rest of the "cleanup" work. If you don't successfully delete it, return/handle the exception, etc.