多线程文件搜索

方法一:递归

代码思路:

1. 定义一个函数`count_files_and_folders`,该函数接受一个目录路径参数,并使用指针引用来传递文件和文件夹数量的统计结果。

2. 在函数内部,使用`opendir`函数打开指定的目录,如果打开失败,输出错误信息并返回。

3. 使用`readdir`函数按顺序读取目录中的每个文件和文件夹。

4. 对于每个读取到的文件和文件夹,先判断是否为`.`或`..`,如果是则跳过。否则,将文件/文件夹名称和目录路径拼接成完整的路径。

5. 使用`stat`函数获取文件/文件夹的详细信息,如果获取失败,输出错误信息并继续处理下一个。

6. 根据文件/文件夹的类型(使用宏`S_ISDIR`判断是否是文件夹),分别做如下处理:

   - 如果是文件夹,则增加文件夹数量,并递归调用`count_files_and_folders`函数,传入当前文件夹的路径,以及文件和文件夹的数量引用。

   - 如果是文件,则增加文件数量。

7. 使用`closedir`函数关闭目录。

8. 在`main`函数中,首先定义文件和文件夹数量的变量。

9. 获取用户输入的指定目录路径。

10. 调用`count_files_and_folders`函数,传入指定目录路径和文件/文件夹数量引用。

11. 输出统计结果。

请注意,缩进和格式只是为了增加代码的可读性,并在不同部分之间代码块之间添加了注释解释。在实际编写中,可以根据自己的习惯和代码风格进行调整。

方法二:多线程

代码思路:

1. 首先,在主函数中指定要搜索的目录。这个目录将被传递给每个线程进行搜索。

2. 初始化互斥锁,用于保护共享的计数器变量。

3. 创建线程数组和参数数组,用于保存线程和参数。

4. 使用一个循环,创建一定数量(64个)的线程,并将搜索目录作为参数传递给每个线程。

5. 在线程函数`search_files_and_directories()`中,首先获取传递的目录路径。

6. 使用`opendir()`函数打开目录,并检查是否成功打开。

7. 在循环中,使用`readdir()`函数读取目录中的每个条目(文件或子目录)。

8. 对于每个条目,构建完整的路径,并根据其类型决定是增加子目录计数还是增加文件计数。

9. 如果是子目录,则递归调用`search_files_and_directories()`函数进行进一步的搜索。

10. 处理完当前目录的所有条目后,使用`closedir()`函数关闭目录。

11. 在主函数中使用`pthread_join()`函数等待所有线程完成。

12. 销毁互斥锁。

13. 输出最终的子目录和文件数量。

总体上,程序使用多线程的方式并行搜索指定目录下的文件和子目录。通过使用互斥锁来保护计数器变量的访问,确保线程之间的安全访问。

每个线程负责搜索目录中的一部分内容,并更新共享计数器变量的值。通过递归调用,线程可以深入搜索子目录。

最后,主线程等待所有线程完成,并输出最终的结果。

#include <stdio.h>
#include <dirent.h>
#include <pthread.h>
#include <string.h>

#define MAX_THREADS 64
#define MAX_PATH_LENGTH 1024

struct ThreadArgs {
    char path[MAX_PATH_LENGTH]; // 存储目录路径
    int file_count; // 存储文件数量
    int folder_count; // 存储文件夹数量
};

void* search_files_and_directories(void* arg) {
    struct ThreadArgs* args = (struct ThreadArgs*)arg;
    char* path = args->path;
    int* file_count = &(args->file_count);
    int* folder_count = &(args->folder_count);

    DIR* directory;
    struct dirent* entry;

    directory = opendir(path); // 打开目录
    if (directory == NULL) {
        printf("Unable to open directory: %s\n", path);
        pthread_exit(NULL);
    }

    while ((entry = readdir(directory)) != NULL) { // 遍历目录下的条目
        if (entry->d_type == DT_DIR) { // 如果是文件夹
            if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
                (*folder_count)++; // 增加文件夹数量
                char sub_path[MAX_PATH_LENGTH];
                snprintf(sub_path, sizeof(sub_path), "%s/%s", path, entry->d_name); // 构建子目录路径

                search_files_and_directories(sub_path); // 递归搜索子目录
            }
        } else if (entry->d_type == DT_REG) { // 如果是文件
            (*file_count)++; // 增加文件数量
        }
    }

    closedir(directory); // 关闭目录

    pthread_exit(NULL);
}

int main(int argc, char* argv[]) {
    if (argc != 2) {
        printf("Usage: %s <directory>\n", argv[0]);
        return 0;
    }

    char* path = argv[1];

    int total_file_count = 0;
    int total_folder_count = 0;

    pthread_t threads[MAX_THREADS];
    struct ThreadArgs thread_args[MAX_THREADS];

    // 初始化线程参数
    for (int i = 0; i < MAX_THREADS; i++) {
        strcpy(thread_args[i].path, path);
        thread_args[i].file_count = 0;
        thread_args[i].folder_count = 0;
    }

    // 创建线程
    for (int i = 0; i < MAX_THREADS; i++) {
        pthread_create(&threads[i], NULL, search_files_and_directories, (void*)&thread_args[i]);
    }

    // 等待线程完成
    for (int i = 0; i < MAX_THREADS; i++) {
        pthread_join(threads[i], NULL);

        total_file_count += thread_args[i].file_count;
        total_folder_count += thread_args[i].folder_count;
    }

    printf("Total number of files: %d\n", total_file_count);
    printf("Total number of folders: %d\n", total_folder_count);

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值