SafeFileHandle 是 .NET 封装 Windows 文件句柄的安全类型,实现 IDisposable 并参与 GC 管理;直接用 IntPtr 易致资源泄漏、双重关闭及崩溃。
SafeFileHandle 是什么,为什么不能直接用 IntPtr
SafeFileHandle 是 .NET 提供的用于封装 Windows 文件句柄(HANDLE)的安全包装器,它实现了 IDisposable 并参与 .NET 的垃圾回收生命周期管理。直接用 IntPtr 存储句柄会导致资源泄漏或双重关闭——因为 GC 不知道该何时释放、也无法保证只释放一次。
常见错误现象:ObjectDisposedException、IOException(“句柄无效”)、程序在高并发文件操作时偶发崩溃。
- 必须继承
SafeHandle并重写ReleaseHandle(),而SafeFileHandle已为你做好了:它调用CloseHandle()且能正确处理INVALID_HANDLE_VALUE - 构造时必须传入有效的非托管句柄,并设
ownsHandle = true(表示托管层负责释放),否则 GC 不会触发清理 - 一旦调用
Dispose()或被 GC 回收,内部handle会被置为IntPtr.Zero,再次访问会抛ObjectDisposedException
如何从 CreateFile 获取 SafeFileHandle
Windows API 的 CreateFile 返回 IntPtr,你需要把它转成 SafeFileHandle 实例——但不能直接 new,必须用它的受保护构造函数,所以得自己封装一层子类,或使用 .NET 5+ 提供的 SafeFileHandle(IntPtr, Boolean) 公共构造函数。
示例(.NET 6+):