C语言实现文件夹内相同内容文件分组

本文介绍使用 C 语言编写程序,遍历指定文件夹,找出其中内容完全相同的文件并进行分组。

实现思路

  1. 遍历指定文件夹,获取所有文件路径。
  2. 对于每个文件,计算它的哈希值(可以使用 MD5 或 SHA1 等算法),并将哈希值作为键,文件路径作为值存入一个哈希表中。
  3. 遍历哈希表,对于每个键值对,如果键对应的值的数量大于 1,则说明有多个文件的内容相同,将它们分为一组。
  4. 输出每组文件的路径。

代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <openssl/md5.h>

#define MAX_PATH 1024
#define HASH_SIZE 1024

typedef struct node {
    char *path;
    struct node *next;
} Node;

Node *hash_table[HASH_SIZE];

void add_to_hash_table(char *path) {
    FILE *fp = fopen(path, 'rb');
    if (fp == NULL) {
        perror('fopen');
        return;
    }
    unsigned char md5[MD5_DIGEST_LENGTH];
    MD5_CTX ctx;
    MD5_Init(&ctx);
    char buf[1024];
    int len;
    while ((len = fread(buf, 1, sizeof(buf), fp)) > 0) {
        MD5_Update(&ctx, buf, len);
    }
    MD5_Final(md5, &ctx);
    fclose(fp);
    char key[MD5_DIGEST_LENGTH * 2 + 1];
    for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
        sprintf(key + i * 2, '%02x', md5[i]);
    }
    key[MD5_DIGEST_LENGTH * 2] = '\0';
    int index = 0;
    for (int i = 0; i < strlen(key); i++) {
        index = (index * 31 + key[i]) % HASH_SIZE;
    }
    Node *p = hash_table[index];
    while (p != NULL) {
        if (strcmp(p->path, path) == 0) {
            return;
        }
        p = p->next;
    }
    Node *node = malloc(sizeof(Node));
    node->path = strdup(path);
    node->next = hash_table[index];
    hash_table[index] = node;
}

void traverse_dir(char *dir) {
    DIR *dp = opendir(dir);
    if (dp == NULL) {
        perror('opendir');
        return;
    }
    struct dirent *entry;
    char path[MAX_PATH];
    while ((entry = readdir(dp)) != NULL) {
        if (strcmp(entry->d_name, '.') == 0 || strcmp(entry->d_name, '..') == 0) {
            continue;
        }
        snprintf(path, sizeof(path), '%s/%s', dir, entry->d_name);
        if (entry->d_type == DT_DIR) {
            traverse_dir(path);
        } else if (entry->d_type == DT_REG) {
            add_to_hash_table(path);
        }
    }
    closedir(dp);
}

void print_groups() {
    for (int i = 0; i < HASH_SIZE; i++) {
        Node *p = hash_table[i];
        if (p == NULL) {
            continue;
        }
        printf('Group:\n');
        while (p != NULL) {
            printf('  %s\n', p->path);
            p = p->next;
        }
    }
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, 'Usage: %s dir\n', argv[0]);
        exit(1);
    }
    memset(hash_table, 0, sizeof(hash_table));
    traverse_dir(argv[1]);
    print_groups();
    return 0;
}

使用方法

  1. 编译:
gcc -o find-duplicate-files find-duplicate-files.c -lcrypto
  1. 运行:
./find-duplicate-files dir

其中,dir是要遍历的文件夹路径。

注意:

  • 该程序需要使用 OpenSSL 库,请确保已安装 OpenSSL 库。
  • 由于哈希表的大小固定,如果文件数量非常多,可能会出现哈希冲突,导致程序无法正确识别相同内容的文件。可以尝试增大 HASH_SIZE 的值来减少哈希冲突的概率。
  • 该程序只比较文件内容,不考虑文件属性(如修改时间、权限等)。
C语言实现文件夹内相同内容文件分组

原文地址: https://www.cveoy.top/t/topic/lfdq 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录