0

In my program I pass the path to a file which may be still being written to by another process (independent external non-c#).

How can I check the file is fully readable and accessible before I actually send the path back to the client? FileIOPermission with Demand for reading did not work for me, so I am wondering if there is some other way of doing this without attempting to read the whole file upfront.

Thank you.

mr.sverrir
  • 414
  • 4
  • 12
  • 1
    http://stackoverflow.com/questions/424830/detecting-whether-a-file-is-locked-by-another-process-or-indeed-the-same-proces – Florian Sep 20 '13 at 13:06

5 Answers5

7

The trouble with checking to see if a file is accessible and fully readable, and then opening the file for reading is that potentially, the state could change between the check and the open where you actually want to be doing something with it.

My suggestion is to go ahead and open the file for reading, being sure to catch the appropriate exception if a problem occurs. You can then wait a little and try again, or do something else.

Remember that just because your program has a sequence of events that are logical to you, many things are going on in an operating system and the state can easily change between two lines of code that seem watertight for you, but have an epoch between them at a multitasking level.

Moo-Juice
  • 38,257
  • 10
  • 78
  • 128
3

Moo-Juice is right. You can't check whether the file can be read successfully and then open it for reading... things can change and you might get an exception anyway. Best to just read it and catch the exception.

public bool TryReadFile(String path, out String contentsOfFile)
{
  try
  {
    // Try reading file
    contentsOfFile = File.ReadAllText(path);
    // Success! Yay!
    return true;
  }
  catch (IOException)
  {
    // Oops! Can't read that file!
    // Return some default value and let the caller know we failed
    contentsOfFile = String.Empty;
    return false;
  }
Jeff B
  • 8,572
  • 17
  • 61
  • 140
1

Best way would be to read the file in a normal try catch block, and then apply the logic to continue or not, based on if an exception was thrown or not.

Also, a secondary way is to check if a file is not of zero size, but purely as a secondary check.

0

Create a loop and try to open the file
If exception occur make your thread sleep for some seconds
and repeat the process

donstack
  • 2,557
  • 3
  • 29
  • 44
0

When the external process is complete, does it close? If so, you could modify the solution found here. It would look something like the following:

//While the process is found running
while (System.Diagnostics.Process.GetProcessesByName(process).Length != 0)
{
     //Sleep for three seconds
     System.Threading.Thread.Sleep(3000);
}

//open file for reading

If the process doesn't close when complete, however, the above won't work. You could try placing the following in a loop that tries to open the file exclusively until it's successful:

System.IO.File.Open(PathToFile, FileMode.Open, FileAccess.Read, FileShare.None);

Both of these methods should also have some kind of count added to ensure that they eventually stop trying and error out, or else you could end up with an infinite loop.

Community
  • 1
  • 1
tmoore82
  • 1,857
  • 1
  • 27
  • 48