自动检查文件是否存在并打开它
Atomically check if a file exists and open it
我试图仅在文件存在时打开 FileStream
,否则执行其他操作(不创建它,因此 FileMode.OpenOrCreate
不适用)。
但是,在创建 FileStream
之前简单地检查 File.Exists
不会阻止竞争条件,因为文件可能会在 FileStream
有机会创建之前被删除,在这种情况下FileNotFoundException
将被抛出。
有没有一种方法可以实现此 "natively",而无需诉诸以下 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调用WindowsAPI的CreateFile()
函数来打开文件。如果文件无法打开,此 returns 为空句柄(尽管您必须调用 GetLastError()
来确定 为什么 文件无法打开).
确保对 CreateFile()
使用 P/Invoke 声明,其中 returns 和 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
.
的 the overload of the FileStream()
构造函数
这与您将获得的 "native" 差不多...
但是,我建议您只捕获异常。
我试图仅在文件存在时打开 FileStream
,否则执行其他操作(不创建它,因此 FileMode.OpenOrCreate
不适用)。
但是,在创建 FileStream
之前简单地检查 File.Exists
不会阻止竞争条件,因为文件可能会在 FileStream
有机会创建之前被删除,在这种情况下FileNotFoundException
将被抛出。
有没有一种方法可以实现此 "natively",而无需诉诸以下 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调用WindowsAPI的CreateFile()
函数来打开文件。如果文件无法打开,此 returns 为空句柄(尽管您必须调用 GetLastError()
来确定 为什么 文件无法打开).
确保对 CreateFile()
使用 P/Invoke 声明,其中 returns 和 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
.
FileStream()
构造函数
这与您将获得的 "native" 差不多...
但是,我建议您只捕获异常。