Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can you easily check if access is denied for a file in .NET?

Basically, I would like to check if I have rights to open the file before I actually try to open it; I do not want to use a try/catch for this check unless I have to. Is there a file access property I can check before hand?

like image 890
Horas Avatar asked Nov 05 '08 17:11

Horas


People also ask

How to access file access Denied?

Right-click the file or folder, and then click Properties. Click the Security tab. Under Group or user names, click your name to see the permissions you have. Click Edit, click your name, select the check boxes for the permissions that you must have, and then click OK.

Why is file access Denied?

Check for File Encryption. Another reason you might see the "access is denied" message is that a folder's contents are encrypted. As you may know, encryption protects a file by only allowing someone with the key to view it.


4 Answers

I have done this countless times in the past, and nearly every time I was wrong to even make the attempt.

File permissions (even file existence) are volatile — they can change at any time. Thanks to Murphy's Law this especially includes the brief period between when you check the file and when you try to open it. There are other reasons this can fail, too, such as locking or network availability and path resolution. An errant result is even more likely if you're in an area where you know you need to check first. Yet strangely enough it will never happen in your testing or development environments, which tend to be fairly static. This makes the problem difficult to track down later and makes it easy for this kind of bug to make it into production.

What this means is you must still be ready to handle the exception if file permissions or existence are bad, in spite of your check. Exception handling code is required, whether or not you check the file in advance, and good exception handler can provide all of the functionality of existence or permissions checks.

But isn't exception handling slow? I'm glad you asked. Yes, yes it is. In fact, unwinding the stack to handle an exception is up there with the slowest stuff you can do inside a single computer. However, it's important to remember that disk I/O is even slower — a lot slower — and calling the .Exists() function or checking permissions will always force an additional I/O operation on the file system.

Therefore, we see an initial check before trying to open the file is both redundant and wasteful. There is no additional benefit over exception handling. It will actually hurt, not help, your performance. It adds cost in terms of more code that must be maintained. Finally, it can introduce subtle bugs. There is just no upside at all to doing the initial check.

Instead, the correct thing here is immediately trying to open the file, with no initial check, and putting your effort into a good exception handler if it fails. The same is true whether you're checking permissions, locking, or even just whether or not the file exists.

In summary: the choice is paying the extra cost for file check every time with more code, or paying the smaller-but-still-bad cost for exception handling only some of the time and with less code.

like image 91
17 revs, 2 users 97% Avatar answered Oct 23 '22 09:10

17 revs, 2 users 97%


Quick tip for anyone else coming here with a similar problem:

Watch out for web synchronization apps such as DropBox. I just spent 2 hours thinking the "using" statement (Dispose pattern) is broken in .NET.

I eventually realised that Dropbox is continually reading and writing files in the background, in order to sync them.

Guess where my Visual Studio Projects folder is located? Inside the "My Dropbox" folder of course.

Therefore as I ran my application in Debug mode, the files it was reading and writing were also continually being accessed by DropBox to be synched with the DropBox server. This caused the locking/access conflicts.

So at least I now know that I need to a more robust File Open function (ie TryOpen() that will make multiple attempts). I am surprised it's not already a built-in part of the framework.

[Update]

Here's my helper function:

/// <summary> /// Tries to open a file, with a user defined number of attempt and Sleep delay between attempts. /// </summary> /// <param name="filePath">The full file path to be opened</param> /// <param name="fileMode">Required file mode enum value(see MSDN documentation)</param> /// <param name="fileAccess">Required file access enum value(see MSDN documentation)</param> /// <param name="fileShare">Required file share enum value(see MSDN documentation)</param> /// <param name="maximumAttempts">The total number of attempts to make (multiply by attemptWaitMS for the maximum time the function with Try opening the file)</param> /// <param name="attemptWaitMS">The delay in Milliseconds between each attempt.</param> /// <returns>A valid FileStream object for the opened file, or null if the File could not be opened after the required attempts</returns> public FileStream TryOpen(string filePath, FileMode fileMode, FileAccess fileAccess,FileShare fileShare,int maximumAttempts,int attemptWaitMS) {     FileStream fs = null;     int attempts = 0;      // Loop allow multiple attempts     while (true)     {         try         {             fs = File.Open(filePath, fileMode, fileAccess, fileShare);              //If we get here, the File.Open succeeded, so break out of the loop and return the FileStream             break;         }         catch (IOException ioEx)         {             // IOExcception is thrown if the file is in use by another process.              // Check the numbere of attempts to ensure no infinite loop             attempts++;             if (attempts > maximumAttempts)             {                 // Too many attempts,cannot Open File, break and return null                  fs = null;                 break;             }             else             {                 // Sleep before making another attempt                 Thread.Sleep(attemptWaitMS);              }          }      }     // Reutn the filestream, may be valid or null     return fs; } 
like image 33
Ash Avatar answered Oct 23 '22 08:10

Ash


First, what Joel Coehoorn said.

Also: you should examine the assumptions that underly your desire to avoid using try/catch unless you have to. The typical reason for avoiding logic that depends on exceptions (creating Exception objects performs poorly) probably isn't relevant to code that's opening a file.

I suppose that if you're writing a method that populates a List<FileStream> by opening every file in a directory subtree and you expected large numbers of them to be inaccessible you might want to check file permissions before trying to open a file so that you didn't get too many exceptions. But you'd still handle the exception. Also, there's probably something terribly wrong with your program's design if you're writing a method that does this.

like image 36
Robert Rossney Avatar answered Oct 23 '22 09:10

Robert Rossney


Here is the solution you are looking for

var fileIOPermission = new FileIOPermission(FileIOPermissionAccess.Read,
                                            System.Security.AccessControl.AccessControlActions.View,
                                            MyPath);

if (fileIOPermission.AllFiles == FileIOPermissionAccess.Read)
{
    // Do your thing here...
}

this creates a new permission of read based on view for path of all files then checks if it's equal to file access read.

like image 30
dj shahar Avatar answered Oct 23 '22 09:10

dj shahar