非遞歸實(shí)現(xiàn)文件夾遍歷
之前有個(gè)電話面試,其中一道題就是:用非遞歸的方式實(shí)現(xiàn)文件夾遍歷?在電面的時(shí)候沒有答出來,過后分分鐘就想到了答案,因?yàn)橹白约簩?shí)現(xiàn)過按層序的方式打印一棵樹,用的也是非遞歸的方式,現(xiàn)在遍歷文件夾不就是遍歷這顆樹嗎!怎么就沒想出來呢!在這里簡(jiǎn)單的記錄下,用了C#和C++兩個(gè)版本實(shí)現(xiàn)。
我這里的實(shí)現(xiàn)的功能是:用非遞歸的方式獲得一個(gè)文件夾中文件的個(gè)數(shù)。
思路簡(jiǎn)單介紹:
1:先將這個(gè)文件夾的路徑加入一個(gè)隊(duì)列中;
2:判斷隊(duì)列的元素個(gè)數(shù)是否大于0,如果元素個(gè)數(shù)大于0,遍歷第一個(gè)元素對(duì)應(yīng)的文件夾,用一個(gè)變量fileCounts記錄這個(gè)文件夾中文件的個(gè)數(shù),如果這個(gè)文件夾中有文件夾,就將這個(gè)文件夾的路徑加入隊(duì)列中,掃描完一個(gè)文件夾后,第一個(gè)元素彈出隊(duì)列,繼續(xù)執(zhí)行第二步,如果隊(duì)列中沒有元素,就執(zhí)行第三步;
3:退出循環(huán)
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<< "文件個(gè)數(shù):"<<QueryFileCounts(L"D:\\feinno\\RunImage")<<endl; } system("pause"); return 0; }
運(yùn)行結(jié)果如下:

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("文件個(gè)數(shù):" + count ); Console.Read(); } } }
運(yùn)行結(jié)果如下:

浙公網(wǎng)安備 33010602011771號(hào)