`
xp9802
  • 浏览: 1204592 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

非递归实现文件夹遍历

 
阅读更多

之前有个电话面试,其中一道题就是:用非递归的方式实现文件夹遍历?在电面的时候没有答出来,过后分分钟就想到了答案,因为之前自己实现过按层序的方式打印一棵树,用的也是非递归的方式,现在遍历文件夹不就是遍历这颗树吗!怎么就没想出来呢!在这里简单的记录下,用了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();
        }
    }
}
复制代码

运行结果如下:

分享到:
评论

相关推荐

    递归遍历与非递归遍历文件夹.pdf

    非递归遍历则内存效率更高,但实现起来可能更复杂,需要手动管理数据结构。在实际应用中,选择哪种遍历方式取决于具体需求,例如,处理深度较大的文件系统时,非递归遍历可能是更好的选择,因为它避免了深度过大的...

    API无递归遍历文件夹模块.rar

    在这个模块中,源码可能是用易语言编写的,用于实现非递归遍历文件夹的功能。 非递归遍历文件夹通常涉及到栈或者队列的数据结构。使用栈,我们可以模拟“后进先出”(LIFO)的行为,而队列则遵循“先进先出”(FIFO...

    使用Java实现文件夹的遍历

    在本文中,我们将介绍使用 Java 实现文件夹的遍历的两种方式:递归遍历和非递归遍历。 递归遍历文件夹 递归遍历文件夹是一种常见的方式,其思路是: 1. 使用 File 封装初始目录 2. 打印这个目录 3. 获取这个目录...

    C#非递归后序遍历文件目录树

    为了实现非递归的后序遍历,我们可以借助数据结构——栈。栈是一种后进先出(LIFO)的数据结构,非常适合用来模拟后序遍历的过程。 以下是一个基本的实现步骤: 1. **初始化栈**:创建一个Stack对象,用于存储待...

    树的遍历,递归和非递归实现方式,工程源码

    本压缩包包含的是关于树的遍历,特别是递归和非递归实现方式的工程源码,这些代码基于C++语言,存放在Dep工程文件夹中。 首先,我们要理解什么是树的遍历。树遍历是指按照特定顺序访问树的所有节点。通常,有三种...

    VC 递归和非递归算法遍历磁盘文件

    递归和非递归算法是两种常用的方法来实现这个功能。这两者都有各自的优点和适用场景,对于新手来说,理解并掌握它们是非常重要的。 首先,我们来看**递归算法**。递归是一种函数或过程调用自身的技术。在遍历文件...

    文件夹遍历与多线程复制文件

    本项目"文件夹遍历与多线程复制文件"着重于五个关键知识点:文件夹非递归遍历、文件操作复制、多线程复制、线程互斥以及MFC非模态对话框的创建和销毁。下面将详细阐述这些知识点。 1. **文件夹非递归遍历**: 在...

    Javascript如何递归遍历本地文件夹

    此外,递归遍历文件系统可能消耗大量资源,尤其是在处理大型文件夹结构时,因此在实际应用中需要考虑性能优化,比如设置递归深度限制或者使用非阻塞异步处理。 总结起来,JavaScript在IE环境下可以通过...

    C++非递归遍历磁盘文件和递归遍历磁盘文件的程序示例

    非递归遍历通常使用栈数据结构来实现。在这个例子中,我们创建了一个名为`Search`的类,它包含了存储文件路径、搜索关键字和保存磁盘ID的栈。关键函数`ListAllFileInDirectory`用于处理目录中的每个文件和子目录。在...

    易语言-非递归算法遍历目录

    在“易语言-非递归算法遍历目录”这个主题中,我们将深入探讨如何使用易语言编写程序,通过非递归算法来遍历一个目录下的所有文件和子目录。 首先,我们要理解“非递归”算法的概念。递归通常是指函数或过程在执行...

    Python实现递归遍历文件夹并删除文件

    ### Python 实现递归遍历文件夹并删除文件 #### 方法一:递归删除特定文件夹(如 .svn) 在本方法中,我们利用Python的标准库`os`和`shutil`来递归地遍历文件夹并删除指定的文件夹(例如`.svn`文件夹)。这种做法...

    Node.js 使用递归实现遍历文件夹中所有文件

    文件夹可以包含子文件夹,子文件夹又可以包含更多的子文件夹和文件,这种层级结构非常适合用递归的方式来遍历。 在Node.js中,可以利用`fs`模块提供的文件系统API来读取和操作文件及文件夹。比如,`fs.readdir`函数...

    如何遍历文件夹查找文件

    - **Python**: 可以使用`os`和`os.path`模块,如`os.walk()`函数用于递归遍历目录。 - **Java**: `java.io.File`类提供了`list()`, `listFiles()`, `listFiles(FileFilter)`等方法。 - **C++**: 使用`...

    易语言遍历目录文件

    易语言是一种专为中国人设计的编程语言,它以简体中文作为编程语法,降低了编程的门槛,使得更多非计算机专业的人也能轻松学习编程。在易语言中,遍历目录文件是一项基本的操作,常用于文件管理和数据处理等场景。...

    VC对磁盘文件遍历搜索的递归算法和非递归算法

    在VC++(Visual C++)环境中,有多种方法可以实现这一目标,其中最常见的是递归算法和非递归算法。这两种方法各有优缺点,适用于不同的场景。 **递归算法**: 递归算法是一种基于函数自身调用解决问题的方法。在...

    java递归与非递归实现扫描文件夹下所有文件

    Java递归与非递归实现扫描文件夹下所有文件 Java递归与非递归实现扫描文件夹下所有文件是Java编程中的一种常见需求,通过递归和非递归两种方式来实现对文件夹下所有文件的扫描。 一、Java递归方式实现扫描文件夹...

    一段代码演示C++根据路径判定是目录还是文件,文件搜索,文件夹遍历等问题.pdf

    这段代码主要展示了如何在C++中使用Windows API和标准库函数来处理文件系统操作,包括判断路径是目录还是文件、文件搜索以及文件夹遍历。以下是对这些知识点的详细解释: 1. **路径判断**: 在C++中,没有像Java...

    Java 遍历文件夹内文件

    描述中提到的链接指向了一篇博客文章,可能详细解释了如何使用Java遍历文件夹,并可能包含了一些实用技巧或者特定的实现案例。遗憾的是,由于我们无法直接访问该链接,所以无法提供更具体的信息。 在标签中,"源码...

    运用Java遍历文件夹的方法总结.doc

    非递归算法实现文件夹遍历 虽然递归算法简洁高效,但在某些情况下(如深度较大的文件树)可能会导致堆栈溢出等问题。这时可以考虑使用非递归算法。下面是一个使用链表实现的非递归遍历示例: ```java package ...

    nodejs实现遍历文件夹并统计文件大小

    实现遍历文件夹功能的代码中,使用了`fs.readdirSync`方法,该方法同步读取目录内容,并返回一个文件名的数组。通过递归调用`readFile`函数,程序能够深入到每一个子目录中继续遍历,对于每一个文件,程序会使用`fs....

Global site tag (gtag.js) - Google Analytics