這是我想出來的。
首先,這是一個例外的壞方法。
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;
}
}
在我的機器上這個方法在文件被使用時花費了大約一千萬個滴答。
另一種方式是使用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;
下面是函數
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;
}
}
}
這跑了約180萬蜱。 來自異常方法的超過800萬個滴答差異。
但是,當文件沒有被使用時意味着不會拋出異常,「BAD」方法的速度是130萬,kernel32.dll是200萬。大約800k蜱更好。因此,如果我知道該文件大約1/10時間未被使用,那麼使用Exception方法會更好。然而,它是一次,與kernel32.dll相比,它是一個非常昂貴的ticks操作。
即使你有一個魔術函數返回一個布爾值 - 就像zvolkov指出的那樣,當你嘗試基於布爾值操作時,仍然可能會遇到異常。我相信最好的辦法是自己鎖定文件,鎖定作者 - 正如我的回答中所述。 – 2009-07-08 19:03:34