views:

391

answers:

4

I'm being completely confused here folks,

My code throws an exception because File.Exists() returns false

public override sealed TCargo ReadFile(string fileName)
{
    if (!File.Exists(fileName))
    {
        throw new ArgumentException("Provided file name does not exist", "fileName");
    }

Visual studio breaks at the throw statement, and I immediately check the value of File.Exists(fileName) in the immediate window. It returns true. When I drag the breakpoint back up to the if statement and execute it again, it throws again.

fileName is an absolute path to a file. I'm not creating the file, nor writing to it (it's there all along). If I paste the path into the open dialog in Notepad, it reads the file without problems.

The code is executing in a background worker. It's the only complicating factor I can think of. I am positive the file has not been opened already, either in the worker thread or elsewhere.

What's going on here?

+6  A: 

I don't know what's going on, but why do you need the File.Exists test at all? What you're really interested in is, "Can I read this file?" Plenty of other things other than File Not Found can go wrong.

Not to mention, doing a File.Exists test is a race condition because the file could go away after you've done the test, but before you open the file. Just open the file, that's the best test you can do to determine whether you can read the file.

Paul Betts
+1, that's the only correct way to do this. File.Exists is there primarily for situations like locking files, where you need only to monitor for another process to create or delete the file and never actually intend to open it.
Joel Coehoorn
Paul, you have a point, I guess. I'll test it.
Tor Haugen
I disagree with this statement. It is prudent to check the file's existence *and also* catch exceptions caused by trying to open a non-existing file. The exceptions could be potentially costly as compared with the additional check and it keeps the code looking cleaner.
Josh Einstein
Well, even though File.Exists() continues to return false, the code further down actually reads the file successfully. So I guess I'll give you the points here. Still pretty mysterious, though.
Tor Haugen
I saw Josh's comment just now, and I tend to agree with him. Still, my code runs. For now.
Tor Haugen
Of course in the OP's example the exception is not avoided at all but the code could certainly be refactored to avoid it.
Josh Einstein
@Josh Doing the Exists test will especially bite you when you're over a network filesystem, it's unnecessary and technically incorrect. The cost of an exception is negligible as soon as you're comparing it to hitting the disk for anything.
Paul Betts
+1  A: 

Well, what is the path of your filename? Remember when you build debug and release you compile to different folders. So if you put the file in the debug folder you won't find it when doing a release build.

Makach
The path is not related to the build. It actually comes out of a call to Directory.GetFiles(), and so definitely should exist.
Tor Haugen
+3  A: 

File.Exists returns false if you do not have permission to access the folder or file referenced. It may be that you can see the file in the immediates window as an administrator, but when running in a different context you do not have permission.

Julian Martin
My guess too. VS is probably running as admin which may explain why the file is visible from the debugger.
jdv
True but if you Run (without debug) from an elevated Visual Studio, the child process would also be elevated.
Josh Einstein
A: 

hmm what sort of things are you doing after this check? make sure you're cleaning up the file state before dragging your breakpoint again.

JDPeckham