public MyFileReader(String fileName) { // Security permission check. String fullPath = Path.GetFullPath(fileName); new FileIOPermission(FileIOPermissionAccess.Read, fullPath).Demand(); // Open a file, and save its handle in _handle. // Note that the most optimized code turns into two processor // instructions: 1) a call, and 2) moving the return value into // the _handle field. With SafeHandle, the CLR's platform invoke // marshaling layer will store the handle into the SafeHandle // object in an atomic fashion. There is still the problem // that the SafeHandle object may not be stored in _handle, but // the real operating system handle value has been safely stored // in a critical finalizable object, ensuring against leaking // the handle even if there is an asynchronous exception. MySafeFileHandle tmpHandle; tmpHandle = NativeMethods.CreateFile(fileName, NativeMethods.GENERIC_READ, FileShare.Read, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero); // An async exception here will cause us to run our finalizer with // a null _handle, but MySafeFileHandle's ReleaseHandle code will // be invoked to free the handle. // This call to Sleep, run from the fault injection code in Main, // will help trigger a race. But it will not cause a handle leak // because the handle is already stored in a SafeHandle instance. // Critical finalization then guarantees that freeing the handle, // even during an unexpected AppDomain unload. Thread.Sleep(500); _handle = tmpHandle; // Makes _handle point to a critical finalizable object. // <Snippet2> // Determine if file is opened successfully. if (_handle.IsInvalid) { throw new Win32Exception(Marshal.GetLastWin32Error(), fileName); } // </Snippet2> }
public MyFileReader(string fileName) { string fullPath = Path.GetFullPath(fileName); //如果未对调用堆栈中处于较高位置的所有调用方授予当前实例所指定的权限,则在运行时强制 System.Security.Security.SecurityException new FileIOPermission(FileIOPermissionAccess.Read, fullPath).Demand(); //Open a file, and save its handle in _handle. //打开一个文件,并将其句柄保存在_handle中 //Note that the most optimized code turns into two processor instructions:1)a call,and 2)moving the return value into the _handle field. //注意,最优的代码将转化为两条处理指令:1)调用 2)将返回值移动到“_handle”字段中 //With SafeHandle,the CLR's platform invoke marshaling layer will store the handle into the SafeHandle object in an atomic fashion. //使用SafeHandle时,CLR平台会调用封送处理层将以原子方式将句柄储存到SafeHandle对象中 //There is still the problem that the SafeHandle object may not be stored in _handle, //but the real operating system handle value has been safely stored in a critical finalizable object, //ensuring against leaking the handle even if there is an asynchronous exception. //这里还有一个问题:SafeHandle对象可能没有被存在_handle中 //但是实际的操作系统句柄值已经安全存储在一个关键的可终结对象中,确保即使存在异常也不会泄漏句柄 MySafeFileHandle tmpHandle; tmpHandle = NativeMethods.CreateFile(fileName, NativeMethods.GENERIC_READ, FileShare.Read, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero); //An async exception here will cause us to run our finalizer with a null _handle, //but MySafeFileHandle's ReleaseHandle code will be invoked to free the handle. //此处异步异常将会导致我们使用空句柄运行终接器,但将调用MySafeFileHandle的ReleaseHandle代码来释放该句柄 //This call to Sleep,run from the fault injection code in Main, will help trigger a race. //这个调用Sleep,从Main中的错误注入代码运行,将助于出发一场比赛。 //But it will not cause a handle leak because the handle is already stored in a SafeHandle instance. //但他不会导致句柄泄漏,因为句柄已存储在SafeHandle实例中 //Critical finalization then guarantees that freeing the handle,even during an unexpected AppDomain unload. //然后,关键终结将确保释放句柄,即使在意外的AppDomain卸载期间也是如此 Thread.Sleep(500); _handle = tmpHandle; //Make _handle point to a critical f inalizable object. //使句柄指向一个关键的可终结对象 //Determine if file is opened successfully. //确保文件打开成功 if (_handle.IsInvalid) { throw new Win32Exception(Marshal.GetLastWin32Error(), fileName); } }
internal extern static int ReadFile(MySafeFileHandle handle, byte[] bytes, int numBytesToRead, out int numBytesRead, IntPtr overlapped_MustBeZero);