zoukankan      html  css  js  c++  java
  • 非递归实现文件夹遍历

    之前有个电话面试,其中一道题就是:用非递归的方式实现文件夹遍历?在电面的时候没有答出来,过后分分钟就想到了答案,因为之前自己实现过按层序的方式打印一棵树,用的也是非递归的方式,现在遍历文件夹不就是遍历这颗树吗!怎么就没想出来呢!在这里简单的记录下,用了C#和C++两个版本实现。

    我这里的实现的功能是:用非递归的方式获得一个文件夹中文件的个数。

    思路简单介绍:

    1:先将这个文件夹的路径加入一个队列中;

    2:判断队列的元素个数是否大于0,如果元素个数大于0,遍历第一个元素对应的文件夹,用一个变量fileCounts记录这个文件夹中文件的个数,如果这个文件夹中有文件夹,就将这个文件夹的路径加入队列中,扫描完一个文件夹后,第一个元素弹出队列,继续执行第二步,如果队列中没有元素,就执行第三步;

    3:退出循环

    C++版如下:

    #include "stdafx.h"
    #include <Windows.h>
    #include <iostream>
    #include <queue>
    using namespace std;
    
    int QueryFileCounts( LPCTSTR Path )
    {
        queue<std::wstring> qFolders; 
        qFolders.push(Path);
    
        int fileCounts = 0;   
        WIN32_FIND_DATA findResult;
        HANDLE handle=NULL;
          
        while(qFolders.size()>0)
        { 
            std::wstring tempFolder = qFolders.front();
            tempFolder.append(L"\*.*");
            handle = FindFirstFile(tempFolder.c_str(), &findResult);
            do
            {   
                if (findResult.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                {
                    if (lstrcmp(L".",findResult.cFileName)==0 || lstrcmp(L"..",findResult.cFileName)==0)
                    {
                        continue;
                    } 
                    tempFolder=qFolders.front();
                    tempFolder.append(L"\").append(findResult.cFileName);
                    qFolders.push(tempFolder); 
                }else{
                    fileCounts++;
                } 
            }
            while (FindNextFile(handle, &findResult));
            qFolders.pop();
        } 
        if (handle)
        {
            FindClose(handle);
            handle = NULL;
        } 
        return fileCounts;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        {    
            cout<< "文件个数:"<<QueryFileCounts(L"D:\feinno\RunImage")<<endl; 
        }
        system("pause");
        return 0;
    }

    运行结果如下:

    C#版代码如下:

    using System;
    using System.Collections.Generic;
    namespace FileFind
    {  
        class Program
        {
            [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);
     
            static int QueryFileCounts( string Path )
            {
                Queue<string> qFolders=new Queue<string>(); 
                qFolders.Enqueue(Path);
                IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
                int fileCounts = 0;   
                WIN32_FIND_DATA FindFileData=new WIN32_FIND_DATA();
                System.IntPtr hFind=INVALID_HANDLE_VALUE;
                  
                while(qFolders.Count>0)
                {
                    string floder=qFolders.Dequeue(); 
                    string tempFolder = floder;
                    tempFolder+="\*.*";
                    hFind = FindFirstFile(tempFolder ,ref FindFileData);
                    if (hFind == INVALID_HANDLE_VALUE)
                    {
                        continue;
                    }
                    do
                    {
                        if ((FindFileData.dwFileAttributes & 0x10) != 0)
                        {
                            if (FindFileData.cFileName.Equals(".") || FindFileData.cFileName.Equals(".."))
                            { 
                                continue;
                            }
                            tempFolder=floder+"\"+FindFileData.cFileName;
                            qFolders.Enqueue(tempFolder); 
                        }else{
                            fileCounts++;
                        } 
                    }
                    while (FindNextFile(hFind,ref FindFileData));
                }
                if (hFind != INVALID_HANDLE_VALUE)
                {
                    FindClose(hFind);
                } 
                return fileCounts;
            }
    
            static void Main(string[] args)
            {
                int count=QueryFileCounts(@"D:\feinno\RunImage");
                Console.WriteLine("文件个数:" + count );
                Console.Read();
            }
        }
    }

    运行结果如下:

  • 相关阅读:
    手写Promise——基于es6的Promise实现(含详细注释)
    手写promise
    package.json里面配置的啥
    package.json配置详解
    package.json的所有配置项及其用法,你都熟悉么
    sass语法进阶小结
    [转]利用vue-cli3快速搭建vue项目详细过程
    vue的接口封装和状态管理
    Vue项目封装请求数据的接口总结
    JSDoc入门使用指南 -- 手摸手教你用JSDoc(超好用的js文档生成工具)
  • 原文地址:https://www.cnblogs.com/hlxs/p/3760827.html
Copyright © 2011-2022 走看看