自动检查文件是否存在并打开它

本文关键字:存在 是否 检查 文件 | 更新日期: 2023-09-27 18:14:46

我试图打开一个FileStream只有当文件存在,并做其他事情否则(不创建它,所以FileMode.OpenOrCreate是不适用的)。

然而,在创建FileStream之前简单地检查File.Exists并不能防止竞争条件,因为文件可能在FileStream有机会创建之前被删除,在这种情况下,FileNotFoundException将被抛出。

是否有一种方法可以"本机"实现此功能,而无需使用以下try catch包装器:

/// <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;
    }
}

自动检查文件是否存在并打开它

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

确保对CreateFile()使用返回SafeHandle的p/Invoke声明,例如:

[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
);

如果你这样做,那么你可以将句柄传递给FileStream()构造函数的重载,该构造函数接受SafeHandle

这是你将得到的最"原生"的…

但是,我建议您只捕获异常