首页 > 代码库 > c#调用api(FindFirstFile,FindNextFile)高效遍历目录文件【转载】

c#调用api(FindFirstFile,FindNextFile)高效遍历目录文件【转载】

在c#下遍历目录,应用最多的应该就是 System.IO.DirectoryInfo.GetDirectories或GetFiles了,但是当目录特别大,文件特别多时,效率不尽人意,此时我们很容易想到三个Win32API函数 FindFirstFile,FindNextFile和FindClose。这三个API搭配使用就能遍历文件和子目录了,而且可以遍历的时候随时中止,避免无谓的操作。在网上搜了一下,发现这方面的文章转载最多的应该就是http://www.cnblogs.com/xdesigner/archive/2006/12/08/586177.html  这篇了,但是按照文中描述的方法,并不能遍历子目录,没办法,就自己想办法,重新写了一个。 

以下为源代码: 

#region 声明WIN32API函数以及结构 **************************************    [Serializable,    System.Runtime.InteropServices.StructLayout      (System.Runtime.InteropServices.LayoutKind.Sequential,      CharSet = System.Runtime.InteropServices.CharSet.Auto      ),    System.Runtime.InteropServices.BestFitMapping(false)]    private struct WIN32_FIND_DATA    {        public int dwFileAttributes;        public int ftCreationTime_dwLowDateTime;        public int ftCreationTime_dwHighDateTime;        public int ftLastAccessTime_dwLowDateTime;        public int ftLastAccessTime_dwHighDateTime;        public int ftLastWriteTime_dwLowDateTime;        public int ftLastWriteTime_dwHighDateTime;        public int nFileSizeHigh;        public int nFileSizeLow;        public int dwReserved0;        public int dwReserved1;        [System.Runtime.InteropServices.MarshalAs          (System.Runtime.InteropServices.UnmanagedType.ByValTStr,          SizeConst = 260)]        public string cFileName;        [System.Runtime.InteropServices.MarshalAs          (System.Runtime.InteropServices.UnmanagedType.ByValTStr,          SizeConst = 14)]        public string cAlternateFileName;    }    [System.Runtime.InteropServices.DllImport      ("kernel32.dll",      CharSet = System.Runtime.InteropServices.CharSet.Auto,      SetLastError = true)]    private static extern IntPtr FindFirstFile(string pFileName, ref WIN32_FIND_DATA pFindFileData);    [System.Runtime.InteropServices.DllImport      ("kernel32.dll",      CharSet = System.Runtime.InteropServices.CharSet.Auto,      SetLastError = true)]    private static extern bool FindNextFile(IntPtr hndFindFile, ref WIN32_FIND_DATA lpFindFileData);    [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]    private static extern bool FindClose(IntPtr hndFindFile);       #endregion    //具体方法函数     Stack<string> m_scopes = new Stack<string>();    private static readonly IntPtr INVALID_HANDLE_VALUE = http://www.mamicode.com/new IntPtr(-1);".")).Demand();        if (path[path.Length - 1] != ‘\\‘)        {            path = path + "\\";        }        Response.Write("文件夹为:"+path+"<br>");        hFind = FindFirstFile(Path.Combine(path,"*"), ref FindFileData);        if(hFind!=INVALID_HANDLE_VALUE)        {            do            {                if (FindFileData.cFileName.Equals(@".") || FindFileData.cFileName.Equals(@".."))                    continue;                if ((FindFileData.dwFileAttributes & 0x10) != 0)                {                    m_scopes.Push(Path.Combine(path, FindFileData.cFileName));                }                else                {                    Response.Write(FindFileData.cFileName+"<br>");                }            }            while (FindNextFile(hFind, ref FindFileData));                    }        FindClose(hFind);        if (m_scopes.Count > 0)        {            path = m_scopes.Pop();            goto start;        }    }//调用方法如下: FindFileInDir(@"D:");