之前有个电话面试,其中一道题就是:用非递归的方式实现文件夹遍历?在电面的时候没有答出来,过后分分钟就想到了答案,因为之前自己实现过按层序的方式打印一棵树,用的也是非递归的方式,现在遍历文件夹不就是遍历这颗树吗!怎么就没想出来呢!在这里简单的记录下,用了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(); } } }
运行结果如下:
相关推荐
非递归遍历则内存效率更高,但实现起来可能更复杂,需要手动管理数据结构。在实际应用中,选择哪种遍历方式取决于具体需求,例如,处理深度较大的文件系统时,非递归遍历可能是更好的选择,因为它避免了深度过大的...
在这个模块中,源码可能是用易语言编写的,用于实现非递归遍历文件夹的功能。 非递归遍历文件夹通常涉及到栈或者队列的数据结构。使用栈,我们可以模拟“后进先出”(LIFO)的行为,而队列则遵循“先进先出”(FIFO...
在本文中,我们将介绍使用 Java 实现文件夹的遍历的两种方式:递归遍历和非递归遍历。 递归遍历文件夹 递归遍历文件夹是一种常见的方式,其思路是: 1. 使用 File 封装初始目录 2. 打印这个目录 3. 获取这个目录...
为了实现非递归的后序遍历,我们可以借助数据结构——栈。栈是一种后进先出(LIFO)的数据结构,非常适合用来模拟后序遍历的过程。 以下是一个基本的实现步骤: 1. **初始化栈**:创建一个Stack对象,用于存储待...
本压缩包包含的是关于树的遍历,特别是递归和非递归实现方式的工程源码,这些代码基于C++语言,存放在Dep工程文件夹中。 首先,我们要理解什么是树的遍历。树遍历是指按照特定顺序访问树的所有节点。通常,有三种...
递归和非递归算法是两种常用的方法来实现这个功能。这两者都有各自的优点和适用场景,对于新手来说,理解并掌握它们是非常重要的。 首先,我们来看**递归算法**。递归是一种函数或过程调用自身的技术。在遍历文件...
本项目"文件夹遍历与多线程复制文件"着重于五个关键知识点:文件夹非递归遍历、文件操作复制、多线程复制、线程互斥以及MFC非模态对话框的创建和销毁。下面将详细阐述这些知识点。 1. **文件夹非递归遍历**: 在...
此外,递归遍历文件系统可能消耗大量资源,尤其是在处理大型文件夹结构时,因此在实际应用中需要考虑性能优化,比如设置递归深度限制或者使用非阻塞异步处理。 总结起来,JavaScript在IE环境下可以通过...
非递归遍历通常使用栈数据结构来实现。在这个例子中,我们创建了一个名为`Search`的类,它包含了存储文件路径、搜索关键字和保存磁盘ID的栈。关键函数`ListAllFileInDirectory`用于处理目录中的每个文件和子目录。在...
在“易语言-非递归算法遍历目录”这个主题中,我们将深入探讨如何使用易语言编写程序,通过非递归算法来遍历一个目录下的所有文件和子目录。 首先,我们要理解“非递归”算法的概念。递归通常是指函数或过程在执行...
### Python 实现递归遍历文件夹并删除文件 #### 方法一:递归删除特定文件夹(如 .svn) 在本方法中,我们利用Python的标准库`os`和`shutil`来递归地遍历文件夹并删除指定的文件夹(例如`.svn`文件夹)。这种做法...
文件夹可以包含子文件夹,子文件夹又可以包含更多的子文件夹和文件,这种层级结构非常适合用递归的方式来遍历。 在Node.js中,可以利用`fs`模块提供的文件系统API来读取和操作文件及文件夹。比如,`fs.readdir`函数...
- **Python**: 可以使用`os`和`os.path`模块,如`os.walk()`函数用于递归遍历目录。 - **Java**: `java.io.File`类提供了`list()`, `listFiles()`, `listFiles(FileFilter)`等方法。 - **C++**: 使用`...
易语言是一种专为中国人设计的编程语言,它以简体中文作为编程语法,降低了编程的门槛,使得更多非计算机专业的人也能轻松学习编程。在易语言中,遍历目录文件是一项基本的操作,常用于文件管理和数据处理等场景。...
在VC++(Visual C++)环境中,有多种方法可以实现这一目标,其中最常见的是递归算法和非递归算法。这两种方法各有优缺点,适用于不同的场景。 **递归算法**: 递归算法是一种基于函数自身调用解决问题的方法。在...
Java递归与非递归实现扫描文件夹下所有文件 Java递归与非递归实现扫描文件夹下所有文件是Java编程中的一种常见需求,通过递归和非递归两种方式来实现对文件夹下所有文件的扫描。 一、Java递归方式实现扫描文件夹...
这段代码主要展示了如何在C++中使用Windows API和标准库函数来处理文件系统操作,包括判断路径是目录还是文件、文件搜索以及文件夹遍历。以下是对这些知识点的详细解释: 1. **路径判断**: 在C++中,没有像Java...
描述中提到的链接指向了一篇博客文章,可能详细解释了如何使用Java遍历文件夹,并可能包含了一些实用技巧或者特定的实现案例。遗憾的是,由于我们无法直接访问该链接,所以无法提供更具体的信息。 在标签中,"源码...
非递归算法实现文件夹遍历 虽然递归算法简洁高效,但在某些情况下(如深度较大的文件树)可能会导致堆栈溢出等问题。这时可以考虑使用非递归算法。下面是一个使用链表实现的非递归遍历示例: ```java package ...
实现遍历文件夹功能的代码中,使用了`fs.readdirSync`方法,该方法同步读取目录内容,并返回一个文件名的数组。通过递归调用`readFile`函数,程序能够深入到每一个子目录中继续遍历,对于每一个文件,程序会使用`fs....