Here is what I came up with.
First here is the bad way of doing it by exception.
public static bool IsFileInUseBadMethod(string filePath)
{
if (!File.Exists(filePath))
{
return false;
}
try
{
using (StreamReader reader = new StreamReader(File.Open(filePath, FileMode.Open, FileAccess.ReadWrite)))
{
return false;
}
}
catch (IOException)
{
return true;
}
}
On my machine this method took about 10 million ticks when the file was in use.
The other way is using the kernel32.dll
// Need to declare the function from the kernel32
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern Microsoft.Win32.SafeHandles.SafeFileHandle CreateFile(string lpFileName, System.UInt32 dwDesiredAccess, System.UInt32 dwShareMode, IntPtr pSecurityAttributes, System.UInt32 dwCreationDisposition, System.UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile);
private static readonly uint GENERIC_WRITE = 0x40000000;
private static readonly uint OPEN_EXISTING = 3;
Here is the function
public static bool IsFileInUse(string filePath)
{
if (!File.Exists(filePath))
{
return false;
}
SafeHandle handleValue = null;
try
{
handleValue = FileHelper.CreateFile(filePath, FileHelper.GENERIC_WRITE, 0, IntPtr.Zero, FileHelper.OPEN_EXISTING, 0, IntPtr.Zero);
bool inUse = handleValue.IsInvalid;
return inUse;
}
finally
{
if (handleValue != null)
{
handleValue.Close();
handleValue.Dispose();
handleValue = null;
}
}
}
This ran in about 1.8 million ticks. Over an 8 million ticks difference from the exception method.
However when file it not in use meaning no exception is thrown the speed of the "BAD" method is 1.3 million and the kernel32.dll is 2 million. About an 800k ticks better. So using the Exception method would be better if I knew the file would be not be in use about 1/10th of the time. However the one time it is, it is an extremely expensive ticks operation compared to the kernel32.dll.