用递归写Win32的文件夹遍历

yizhihongxing

Win32是Windows应用程序编程接口的一部分,用于编写Windows平台的应用程序。在Win32中,遍历文件夹是一项非常常见的任务。其中之一的实现方式是递归。本文将介绍使用递归编写Win32文件夹遍历的完整攻略,包括以下步骤:

步骤一:准备工作

首先需要引入主文件:

#include <Windows.h>
#include <iostream>
#include <stack>

using namespace std;

在Win32平台上遍历文件夹需要调用相关的API函数,因此需要引入Windows.h头文件。另外,使用stack数据结构来存储文件夹路径。

然后需要定义一个遍历文件夹的函数:

void TraverseDirectory(const string& path);

此函数将接收文件夹的路径作为参数。

步骤二:递归遍历

在函数 TraverseDirectory 中,首先需要定义一个 WIN32_FIND_DATA 结构体,以存储当前文件夹中的每个文件的信息:

WIN32_FIND_DATA fd;

接下来,需要调用 FindFirstFile 函数,以查找该文件夹的第一个文件。如果该函数成功执行,则返回第一个文件的句柄:

HANDLE handle = FindFirstFile((path + "/*").c_str(), &fd);

其中,(path + "/*") 是遍历的目标文件夹路径,/代表分隔符。

如果查找失败,则退出:

if (handle == INVALID_HANDLE_VALUE) {
    return;
}

否则,可以依次遍历目标文件夹中的每一个文件/文件夹,其中遍历到的文件和文件夹的名称存储在 WIN32_FIND_DATA 结构体中的 cFileName 字段中。可以通过判断此处名称是否为“.” 或 “..”来过滤掉文件夹的特殊路径:

do {
    if (strcmp(fd.cFileName, ".") != 0 && strcmp(fd.cFileName, "..") != 0) {
        // Handle file or directory
    }
} while (FindNextFile(handle, &fd));

如果遍历到的文件是一个目录,则需要以递归的方式进行遍历,以便访问该目录中的每个文件。此处在堆栈中记录该目录的路径,并在递归调用 TraverseDirectory 函数时将该路径作为参数传递到函数中:

if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
    stack<string> directories;
    directories.push(path + "/" + fd.cFileName);
    while (!directories.empty()) {
        TraverseDirectory(directories.top());
        directories.pop();
    }
}

最后,清理资源:

FindClose(handle);

示例一:只打印文件名并过滤.txt文件

void TraverseDirectory(const string& path) {
    WIN32_FIND_DATA fd;
    HANDLE handle = FindFirstFile((path + "/*").c_str(), &fd);

    if (handle == INVALID_HANDLE_VALUE) {
        return;
    }

    do {
        if (strcmp(fd.cFileName, ".") == 0 || strcmp(fd.cFileName, "..") == 0) {
            continue;
        }

        if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            stack<string> directories;
            directories.push(path + "/" + fd.cFileName);
            while (!directories.empty()) {
                TraverseDirectory(directories.top());
                directories.pop();
            }
        } else {
            string fileName = fd.cFileName;
            if (fileName.rfind(".txt") == fileName.length() - 4) {
                cout << fileName.substr(0, fileName.length() - 4) << endl;
            }
        }
    } while (FindNextFile(handle, &fd));

    FindClose(handle);
}

int main() {
    TraverseDirectory("C:/testfolder");
    return 0;
}

该示例程序只输出.txt文件名,其他文件将被忽略,输出结果如下:

file1
file2
file3

示例二:输出路径并忽略系统文件夹

void TraverseDirectory(const string& path) {
    WIN32_FIND_DATA fd;
    HANDLE handle = FindFirstFile((path + "/*").c_str(), &fd);

    if (handle == INVALID_HANDLE_VALUE) {
        return;
    }

    do {
        if (strcmp(fd.cFileName, ".") == 0 || strcmp(fd.cFileName, "..") == 0) {
            continue;
        }

        if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)) {
                cout << path + "/" + fd.cFileName << endl;
                stack<string> directories;
                directories.push(path + "/" + fd.cFileName);
                while (!directories.empty()) {
                    TraverseDirectory(directories.top());
                    directories.pop();
                }
            }
        }
    } while (FindNextFile(handle, &fd));

    FindClose(handle);
}

int main() {
    TraverseDirectory("C:/testfolder");
    return 0;
}

该示例程序输出文件夹的路径,但忽略了系统文件夹,避免了系统文件夹误删除等问题,输出结果如下:

C:/testfolder/subfolder1
C:/testfolder/subfolder1/subfolder2
C:/testfolder/subfolder1/subfolder2/subfolder3

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:用递归写Win32的文件夹遍历 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • oracle删除数据文件

    以下是Oracle删除数据文件的完整攻略,包括以下内容: 删除数据文件的概述 删除数据文件的基本用法 删除数据文件的高级用法 示例说明 1. 删除数据文件的概述 在Oracle数据库中,数据文件是存储数据的重要组成部分。有时候,需要删除一个或多个数据文件,例如当需要释放磁盘空间或者需要重新组织数据库时。删除数据文件需要谨慎操作,因为一旦删除,其中的数据将永久…

    other 2023年5月9日
    00
  • 详解Java Socket通信封装MIna框架

    详解Java Socket通信封装Mina框架 1. Java Socket通信介绍 Java Socket通信是一种网络通信方式,它是TCP/IP协议的一种实现。在Java中,Socket通信通常被用于构建客户端和服务器端应用程序。Java Socket通信可以使用Java中的Socket类和ServerSocket类来实现。 在Java Socket通信…

    other 2023年6月25日
    00
  • windows 文件名太长怎么办?Windows关闭/开启短文件名功能的教程

    当Windows文件名太长时,会导致一些操作无法完成。这时可以尝试开启短文件名功能或者缩短文件名来解决问题。下面将详细介绍这两种解决方法。 问题原因及现象 当Windows文件名超过260个字符时,有些操作会因文件名太长而出现问题。出现这种情况的原因通常是由于文件夹目录结构复杂或文件名过长。 解决方法 解决这个问题的方法有两个: 开启短文件名功能 缩短文件名…

    other 2023年6月26日
    00
  • 【matlab】膨胀

    【Matlab】膨胀的完整攻略 膨胀(Dilation)是数字图像处理中的一种形态学操作,它可以将图像中的物体边界向外扩张,从而使物体变得更加粗壮。在Matlab中,我们可以使用imdilate函数实现膨胀操作。本文将详细介绍膨胀的原理、应用场景、使用方法以及两个示例说明。 膨胀的原理 膨胀操作的原理是将一个结构元素在图像上滑动,如果结构元素与图像的某一部分…

    other 2023年5月5日
    00
  • 使用 React hooks 实现类所有生命周期

    使用 React hooks 实现类所有生命周期的攻略可以分为以下步骤: 1. 引入 React 和 React hooks 首先,在使用 React hooks 实现类所有生命周期的过程中,我们需要引入 React 和 React hooks,以便在代码中使用相应的 API。 import React, { useState, useEffect, use…

    other 2023年6月27日
    00
  • mac平台最好用的万能开源免费播放器-iina

    IINA攻略 IINA是一款Mac平台上的开源免费播放器,支持多种视频格式和音频格式,具有简洁的界面和强大的功能。以下是IINA的完整攻略,包括安装、使用和示例说明。 安装 IINA可以在官网下载安装包进行安装,也可以使用Homebrew进行安装。以下是使用Homebrew进行安装的步骤: 打开终端,输入以下命令安装Homebrew: /bin/bash -…

    other 2023年5月5日
    00
  • 为什么要学习C语言 C语言优势分析

    为什么要学习C语言? C语言是一门广泛使用的计算机编程语言。许多操作系统、程序和应用软件都是用C语言进行开发的,而且C语言的语法和结构对于初学者来说比其他高级语言更为基础。此外,C语言还有以下优势: 1. 速度和效率高 C语言编译后可以生成高效的机器码,因此C语言的程序能够在计算机中快速地运行。同时,C语言直接对计算机的底层进行控制,可以实现高效的内存管理和…

    other 2023年6月27日
    00
  • 如何批量创建不同命名的文件夹?创建不同命名文件夹的方法

    可以使用以下三种方法,来批量创建不同命名的文件夹。 方法一:使用命令行 在Windows系统中可以使用命令行的方式创建不同名称的文件夹,具体步骤如下: 打开命令提示符(Win+R 键,输入cmd,回车); 针对所需创建的文件夹个数输入一行命令,在命令行窗口中回车并等待执行完成(这里以创建10个文件夹为例): for /l %i in (1,1,10) do …

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部