1

I check for the existence of the file with File.Exists(filePath). Then I try to open the file from within Excel with Excel.Workbooks.OpenText(filePath). But Excel complains that the file's not there. What the heck?

The context is that I am shelling out to another application to process a given file and produce a .out file, which I then convert to an Excel workbook.

'' At this point, filePath is a .txt file.
Dim args As String = String.Format("""{0}""", filePath)
...
Dim exe As String = Config.ExtractEXE

Dim i As New ProcessStartInfo(exe)
i.Arguments = args

Dim p As Process = Process.Start(i)
p.WaitForExit()
...
'' filePath now becomes the .out file.
'' Then eventually, I get around to checking:
'If Not File.Exists(filePath) Then
'   MsgBox("Please ensure...")
'   Exit Sub
'End If
'' In response to an answer, I no longer check for the existence of the file, but
'' instead try to open the file.

Private Function fileIsReady(filePath As String) As Boolean
  Try
    Using fs As FileStream = File.OpenRead(filePath)
      Return True
    End Using
  Catch
    Return False
  End Try
End Function

Do Until fileIsReady(filePath)
  '' Wait.
Loop

ExcelFile.Convert(filePath...)
'' Wherein I make the call to:
Excel.Workbooks.OpenText(filePath...)
'' Which fails because filePath can't be found.

Is there a latency issue, such that .Net recognizes the existence of the file before it's accessible to other applications? I just don't understand why File.Exists() can tell me the file is there and then Excel can't find it.

As far as I know, the only application that might have the file open is the application I call to do the processing. But that application should be finished with the file by the time p.WaitForExit() finishes, right?

I've had to deploy the application with this as a known bug, which really sucks. There's an easy workaround for the user; but still--this bug should not be. Hope you can help.

Rob
  • 26,989
  • 16
  • 82
  • 98
Jeff Maner
  • 1,179
  • 9
  • 23

1 Answers1

2
  1. Whether or not a file exists is not the only factor in whether you can open it. You also need to look at file system permissions and locking.
  2. File.Exists can lie to you (it returns false if you pass a directory path or if any error occurs, even if the file does exist)
  3. The file system is volatile, and things can change even in the brief period between an if (File.Exists(...)) line and trying to open the file in the next line.

In summary: you should hardly ever use file.exists(). Almost any time you are tempted to do so, just try to open the file and make sure you have a good exception handler instead.

Community
  • 1
  • 1
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • Wow. That's the first I've heard of not relying on File.Exists(). That's a bummer. But I've made changes to the code based on what I've read in your link. Please see my question for the changes. The results are the same. :( – Jeff Maner Dec 18 '12 at 15:48
  • 1
    I think you missed the point. Don't use a function like FileIsReady() at all. You need to put your calls to excel in a try/catch block. – Joel Coehoorn Dec 18 '12 at 16:18
  • Ah. I see. You're right--I did miss the point. Any ideas on why Excel can't open the file that's there? Assuming I'll wrap an exception handler around the Excel code, it's still going to result in a failure to open the file. So my bug is still there. I need to squash that bug! – Jeff Maner Dec 18 '12 at 22:10
  • probably the previous process has not fully released it yet, and the file is still locked. – Joel Coehoorn Dec 18 '12 at 22:38
  • Interesting. I added two layers of Try... Catch blocks: one around the call to Excel.Workbooks.OpenText(), in the Catch block of which I dispose of Excel and re-throw the exception; and the other around ExcelFile.Convert(), in the Catch block of which I wait one second and try my call to ExcelFile.Convert() again. Neither block makes any difference. I still get .Net's Unhandled Exception message telling me the same thing it told me before I added the Try... Catch blocks. – Jeff Maner Dec 21 '12 at 15:51