2015-09-28 109 views
2

我试图只在文件存在时才打开FileStream,否则做别的事情(不创建它,所以FileMode.OpenOrCreate不适用)。原子检查一个文件是否存在并打开它

然而,简单地创建FileStream不会阻止竞争条件为FileStream,必须创建一个机会,在这种情况下FileNotFoundException将被抛出之前文件就可以删除之前检查File.Exists

有没有办法实现这个“原生地”,而不诉诸以下尝试捕捉包装:

/// <returns>false if the file does not exists, true otherwise.</returns> 
public static bool TryOpenFileStreamIfExists(string filePath, FileAccess fileAccess, FileShare fileShare, out FileStream fs, FileOptions fileOptions = FileOptions.None) { 
    try { 
     if (!File.Exists(filePath)) { 
      fs = null; 
      return false; 
     } 
     fs = new FileStream(filePath, FileMode.Open, fileAccess, fileShare, short.MaxValue, fileOptions); 
     return true; 
    } 
    catch (FileNotFoundException) { 
     fs = null; 
     return false; 
    } 
} 
+0

这种情况下try/catch包装器有什么问题? –

+1

这似乎是一个合适的解决方案。 File.Exist调用将处理大多数情况,捕获将处理特例。 – Dennisch

回答

4

你可以使用P/Invoke来调用Windows API的CreateFile()函数打开该文件。如果文件无法打开,则返回空句柄(尽管您必须致电GetLastError()才能确定为什么文件无法打开)。

确保您使用CreateFile()在P/Invoke的声明,它返回一个SafeHandle,如:

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
static extern SafeFileHandle CreateFile 
(
    string lpFileName, 
    [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess, 
    [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode, 
    IntPtr lpSecurityAttributes, 
    [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition, 
    [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes, 
    IntPtr hTemplateFile 
); 

如果你这样做,那么你可以将句柄传递给the overload of the FileStream()构造函数接受SafeHandle

这是我们所“原生”,你会得到...

不过,我建议你刚刚捕获异常。

相关问题