如何通过C#来操作文件句柄

时间:2022-12-11 21:33:58

首先,来说一下什么是文件句柄。百度百科的解释是:在文件I/O中,要从一个文件读取数据,应用程序首先要调用操作系统函数并传送文件名,并选一个到该文件的路径来打开文件。该函数取回一个顺序号,即文件句柄(file handle),该文件句柄对于打开的文件是唯一的识别依据。要从文件中读取一块数据,应用程序需要调用函数ReadFile,并将文件句柄在内存中的地址和要拷贝的字节数传送给操作系统。当完成任务后,再通过调用系统函数来关闭该文件。

来说下应用场景,举个简单的例子,比如说你想操作某个文件,但是在操作的时候不想让其他程序(进程)访问这个文件,这时候我们就需要用到句柄了。

下面就是一个简单的代码例子,可以直接拿来使用。

        /// <summary>
        /// 文件句柄操作类
        /// </summary>
        public class FileHandleAPI
        {

            private const int OF_READWRITE = 2;
            private const int OF_SHARE_DENY_NONE = 0x40;
            private static readonly IntPtr HFILE_ERROR = new IntPtr(-1);


            /// <summary>
            /// 获取文件句柄
            /// </summary>
            /// <param name="lpPathName">file path</param>
            /// <param name="iReadWrite"></param>
            /// <returns></returns>
            [DllImport("kernel32.dll")]
            private static extern IntPtr _lopen(string lpPathName, int iReadWrite);

            /// <summary>
            /// 关闭文件句柄
            /// </summary>
            /// <param name="hObject"></param>
            /// <returns></returns>
            [DllImport("kernel32.dll")]
            private static extern bool CloseHandle(IntPtr hObject);

            /// <summary>
            /// 检查当前文件的句柄是否被占用
            /// </summary>
            /// <param name="filePath">file path</param>
            /// <returns></returns>
            public static bool IsOpen(string filePath)
            {
                IntPtr vHandle = _lopen(filePath, OF_READWRITE | OF_SHARE_DENY_NONE);
                if (vHandle == HFILE_ERROR)
                {
                    CloseHandle(vHandle);
                    return true;
                }
                else
                {
                    CloseHandle(vHandle);
                    return false;
                }              
            }
        }