zoukankan      html  css  js  c++  java
  • 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 = new IntPtr(-1);
        WIN32_FIND_DATA FindFileData;
        private System.IntPtr hFind = INVALID_HANDLE_VALUE;
        void FindFileInDir(string rootDir)
        {
            string path = rootDir;
            start:
            new FileIOPermission(FileIOPermissionAccess.PathDiscovery, Path.Combine(path, ".")).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:");
    
  • 相关阅读:
    EF 错误解决
    TortoiseHg 学习笔记 (转)
    Mysql 命令行 使用 (转)
    2017-9-3 时间字符串格式化(转)
    2017-8-25 c# 获取url参数的五种方法(转)
    alert 的使用方法
    表单关键字查询写法
    Mysql和Mysqli的区别
    php MySQL中 增、删、改、查的写法格式
    一维、二维数组 与 常用的返回数组 以及 fetch_all与fetch_row的区别
  • 原文地址:https://www.cnblogs.com/dekevin/p/3926608.html
Copyright © 2011-2022 走看看