以原子方式检查文件是否存在并将其打开

时间:2015-09-28 12:35:34

标签: c# io filesystems race-condition

我正在尝试仅在文件存在时打开FileStream,否则执行其他操作(不创建它,因此FileMode.OpenOrCreate不适用)。

但是,在创建File.Exists之前简单地检查FileStream不会阻止竞争条件,因为在FileStream有机会创建之前可以删除文件,在这种情况下{ {1}}会被抛出。

有没有办法实现“原生”​​,而不需要使用以下try catch包装器:

FileNotFoundException

1 个答案:

答案 0 :(得分: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
);

如果您这样做,那么您可以将句柄传递给接受SafeHandle的{​​{3}}构造函数。

这就像你将要获得的“原生”......

但是,我建议您抓住异常。