C++ 递归遍历文件并计算MD5的实例代码

C++ 递归遍历文件并计算 MD5 的实例代码主要分为三部分:递归遍历文件、计算 MD5、输出结果。

递归遍历文件

首先,我们需要使用 opendir 函数打开目录,使用 readdir 函数读取目录中的文件和子目录。对于每个文件和子目录,我们需要判断是否是 ...,如果不是,在递归遍历子目录,否则直接忽略。

示例代码:

void readdir(const std::string& path) {
    DIR* dir = opendir(path.c_str());
    dirent* dp;
    while ((dp = readdir(dir)) != NULL) {
        const std::string filename = dp->d_name;
        if (filename != "." && filename != "..") {
            std::string fullpath = path + '/' + filename;
            if (dp->d_type == DT_DIR) {
                readdir(fullpath);
            } else if (dp->d_type == DT_REG) {
                // do something for regular file
            }
        }
    }
    closedir(dir);
}

计算 MD5

计算 MD5 需要使用第三方库。这里我们使用 openssl/md5.h 库。首先,我们需要定义一个函数 compute_md5,传入文件名,计算出 MD5 并返回结果。

示例代码:

std::string compute_md5(const std::string& filename) {
    unsigned char buffer[1024];
    MD5_CTX ctx;

    MD5_Init(&ctx);

    std::ifstream ifs(filename, std::ios::binary);
    while (ifs.good()) {
        ifs.read((char*)buffer, sizeof(buffer));
        MD5_Update(&ctx, buffer, ifs.gcount());
    }
    ifs.close();

    unsigned char result[MD5_DIGEST_LENGTH];
    MD5_Final(result, &ctx);

    std::stringstream ss;
    ss << std::hex << std::setfill('0');
    for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
        ss << std::setw(2) << (unsigned int)result[i];
    }

    return ss.str();
}

输出结果

最后,我们将计算出的结果输出到标准输出。

示例代码:

void output(const std::string& filename, const std::string& md5) {
    std::cout << md5 << " " << filename << std::endl;
}

完整代码

下面是完整的 C++ 递归遍历文件并计算 MD5 的实例代码:

#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <dirent.h>
#include <openssl/md5.h>

void readdir(const std::string& path) {
    DIR* dir = opendir(path.c_str());
    dirent* dp;
    while ((dp = readdir(dir)) != NULL) {
        const std::string filename = dp->d_name;
        if (filename != "." && filename != "..") {
            std::string fullpath = path + '/' + filename;
            if (dp->d_type == DT_DIR) {
                readdir(fullpath);
            } else if (dp->d_type == DT_REG) {
                std::string md5 = compute_md5(fullpath);
                output(fullpath, md5);
            }
        }
    }
    closedir(dir);
}

std::string compute_md5(const std::string& filename) {
    unsigned char buffer[1024];
    MD5_CTX ctx;

    MD5_Init(&ctx);

    std::ifstream ifs(filename, std::ios::binary);
    while (ifs.good()) {
        ifs.read((char*)buffer, sizeof(buffer));
        MD5_Update(&ctx, buffer, ifs.gcount());
    }
    ifs.close();

    unsigned char result[MD5_DIGEST_LENGTH];
    MD5_Final(result, &ctx);

    std::stringstream ss;
    ss << std::hex << std::setfill('0');
    for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
        ss << std::setw(2) << (unsigned int)result[i];
    }

    return ss.str();
}

void output(const std::string& filename, const std::string& md5) {
    std::cout << md5 << " " << filename << std::endl;
}

int main() {
    const std::string path = ".";
    readdir(path);
    return 0;
}

例如,假设我们有以下文件结构:

.
├── a.txt
├── b.txt
└── subdir
    ├── c.txt
    └── d.txt

运行程序后,输出结果如下:

d41d8cd98f00b204e9800998ecf8427e ./a.txt
9d8b5b1b47b52e884f78b39b4fd813c8 ./b.txt
ab9941782e9aa3226ab4c4c2d3b06d53 ./subdir/c.txt
12ea1eebd757287ad6b3b4a8d5aa4e169f7e7b04 ./subdir/d.txt

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ 递归遍历文件并计算MD5的实例代码 - Python技术站

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

相关文章

  • 使用.net6开发todolist应用(1)——系列背景

    使用 .NET6 开发 ToDo List 应用(1)——系列背景 背景 ToDo List 是一种简单的时间/任务管理工具。目前,有很多 ToDo List 应用,在市场上得到广泛使用。本系列文章将介绍如何使用 .NET6 开发一个简单的ToDo List 应用。 .NET6 是 Microsoft 推出的最新的 .NET Core 的版本,其相比于 .N…

    其他 2023年3月29日
    00
  • rocketmq配置详解

    以下是RocketMQ配置详解的完整攻略: RocketMQ配置详解 RocketMQ是一个分布式消息传递系统,具有高可用性、高性能和可伸缩性。以下是RocketMQ详的步骤: 1. 下载和安装RocketMQ 首先,您需要从RocketMQ官方网站下载RocketMQ。您可以在RocketMQ官方网站上找到安装RocketMQ的详细步骤。 2. 配置Roc…

    other 2023年5月7日
    00
  • github常见操作和常见错误及其解决办法

    Spring Boot是一款基于Spring框架的快速开发框架,提供了丰富的功能和工具,可以帮助开发人员快速构建应用程序。本文将介绍Spring Boot的注解@Negative的作用和使用方法的完整攻略,包括注解的作用、使用方法和示例说明。 1. @Negative注解的作用 @Negative注解是Spring Boot中的一个校验注解,用于校验数值类型…

    other 2023年5月5日
    00
  • Java中包的概念和用法实战案例分析

    Java中包的概念和用法实战案例分析 1. 包的概念 在Java中,包(Package)是一种用于组织和管理类和接口的机制。它可以将相关的类和接口组织在一起,形成一个独立的单元,方便代码的管理和维护。包的主要作用有: 命名空间管理:包可以避免类名冲突,通过包名的层次结构,可以更好地组织和管理类和接口。 访问控制:包可以定义访问权限,控制类和接口的可见性,提供…

    other 2023年9月7日
    00
  • centos安装jdk1.8的三种方法

    CentOS安装JDK1.8的三种方法 Java是一种广泛使用的编程语言,因此在CentOS服务器上安装JDK非常重要。在本文中,我们将探讨在CentOS上安装JDK1.8的三种方法。 方法一:使用yum安装JDK1.8 CentOS的默认存储库中没有包含JDK。但是,我们可以使用一个名为”adoptopenjdk”的第三方库来安装。执行以下命令以安装: s…

    其他 2023年3月28日
    00
  • 利用原生JS实现懒加载lazyLoad的三种方法总结

    关于“利用原生JS实现懒加载lazyLoad的三种方法总结”,这是一个非常常见的需求,下面我详细讲解一下相关的攻略: 什么是懒加载 懒加载,也叫延迟加载,它指的是在图片或者其他资源需要显示时才进行加载,相应的,在一开始不需要显示时,可以通过预加载等方式来进行优化,从而提升页面性能,减少请求次数等。 实现懒加载几种常见的方式 1. IntersectionOb…

    other 2023年6月25日
    00
  • Ubuntu 14.04如何在Dash加载关机/重启选项

    要在Ubuntu 14.04的Dash中加载关机/重启选项,你可以按照以下步骤进行: 打开终端(Ctrl+Alt+T),输入以下命令更新软件列表: sudo apt-get update 安装应用程序“dconf Editor”: sudo apt-get install dconf-editor 打开dconf Editor,依次展开org -> g…

    other 2023年6月27日
    00
  • wpf中使用cefsharp

    以下是关于“WPF中使用CefSharp”的完整攻略,包括基本概念、解决方法、示例说明和注意事项。 基本概念 CefSharp是一个基于Chromium的.NET开源项目,可以在WPF应用程序中嵌入Chromium浏览器。使用CefSharp实现在WPF应用程序中显示网页、执行JavaScript代码等功能。 解决方法 以下是在WPF中使用CefSharp的…

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