views:

300

answers:

2

Is there any way to first test if a file is in use before attempting to open it for reading? For example, this block of code will throw an exception if the file is still being written to or is considered in use:

try
{
    FileStream stream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read);
}
catch (IOException ex)
{
    // ex.Message == "The process cannot access the file 'XYZ' because it is being used by another process."
}

I've looked all around and the best I can find is to perform some sort of polling with a try catch inside, and that feels so hacky. I would expect there to be something on System.IO.FileInfo but there isn't.

Any ideas on a better way?

+3  A: 

"You can call the LockFile API function through the P/Invoke layer directly. You would use the handle returned by the SafeFileHandle property on the FileStream. Calling the API directly will allow you to check the return value for an error condition as opposed to resorting to catching an exception."

"The try/catch block is the CORRECT solution (though you want to catch IOException, not all exceptions). There's no way you can properly synchronize, because testing the lock + acquiring the lock is not an atomic operation."

"Remember, the file system is volatile: just because your file is in one state for one operation doesn't mean it will be in the same state for the next operation. You have to be able to handle exceptions from the file system."

http://stackoverflow.com/questions/698442/using-c-is-it-possible-to-test-if-a-lock-is-held-on-a-file

http://www.dotnet247.com/247reference/msgs/32/162678.aspx

cakeforcerberus
I'm not so concerned about it being atomic. That link talked about being able to check via P/Invoke. Where can I find more info on that to see if it helps at all?
McKAMEY
@McKAMEY: Check the second link I just added.
cakeforcerberus
Since file system changes are always possible the correct answer is to try it and deal with the exception if it happens. Besides, it's easier to simply ask for it than to jump through hoops to find out if it's in use.
Loren Pechtel
Answer begrudgingly accepted :)
McKAMEY
A: 

Well a function that would try and do it would simply try catch in a loop. Just like with databases, the best way to find out IF you can do something is to try and do it. If it fails, deal with it. Unless your threading code is off, there is no reason that your program shouldn't be able to open a file unless the user has it open in another program.

Unless of course you're doing interesting things.

Spence
I'm trying to do interesting things :) In my particular case these can be long running locks and I'd like to not be paying the price for try-catch in a loop. The occasional is fine, but it is potentially more common than an exceptional circumstance.
McKAMEY