非遞歸實現文件夾遍歷


之前有個電話面試,其中一道題就是:用非遞歸的方式實現文件夾遍歷?在電面的時候沒有答出來,過后分分鍾就想到了答案,因為之前自己實現過按層序的方式打印一棵樹,用的也是非遞歸的方式,現在遍歷文件夾不就是遍歷這顆樹嗎!怎么就沒想出來呢!在這里簡單的記錄下,用了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();
        }
    }
}

運行結果如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM