centos

如何在CentOS中使用readdir优化代码

小樊
33
2025-08-10 17:16:40
栏目: 智能运维

在CentOS中使用readdir优化代码,通常涉及到对目录进行高效的遍历。readdir是POSIX标准库函数,用于读取目录中的条目。以下是一些优化建议和示例代码:

1. 使用opendirreaddir

首先,确保你使用的是opendirreaddir来遍历目录。这是最基本也是最常用的方法。

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

void list_directory(const char *path) {
    DIR *dir = opendir(path);
    if (dir == NULL) {
        perror("opendir");
        return;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_type == DT_REG) { // 只列出普通文件
            printf("%s\n", entry->d_name);
        }
    }

    closedir(dir);
}

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

    list_directory(argv[1]);
    return EXIT_SUCCESS;
}

2. 减少系统调用

每次调用readdir都会产生一次系统调用,这可能会影响性能。可以通过减少不必要的系统调用来优化。

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

void list_directory_optimized(const char *path) {
    DIR *dir = opendir(path);
    if (dir == NULL) {
        perror("opendir");
        return;
    }

    struct dirent *entry;
    char full_path[PATH_MAX];
    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_type == DT_REG) { // 只列出普通文件
            snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);
            printf("%s\n", full_path);
        }
    }

    closedir(dir);
}

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

    list_directory_optimized(argv[1]);
    return EXIT_SUCCESS;
}

3. 使用多线程

如果目录非常大,可以考虑使用多线程来并行处理目录条目。

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

#define NUM_THREADS 4

typedef struct {
    const char *path;
    int start;
    int end;
} thread_data_t;

void *list_directory_thread(void *arg) {
    thread_data_t *data = (thread_data_t *)arg;
    DIR *dir = opendir(data->path);
    if (dir == NULL) {
        perror("opendir");
        pthread_exit(NULL);
    }

    struct dirent *entry;
    int count = 0;
    while ((entry = readdir(dir)) != NULL && count < data->end - data->start) {
        if (entry->d_type == DT_REG) { // 只列出普通文件
            printf("%s\n", entry->d_name);
        }
        count++;
    }

    closedir(dir);
    pthread_exit(NULL);
}

void list_directory_multithreaded(const char *path, int num_threads) {
    DIR *dir = opendir(path);
    if (dir == NULL) {
        perror("opendir");
        return;
    }

    struct dirent *entry;
    int total_files = 0;
    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_type == DT_REG) { // 只列出普通文件
            total_files++;
        }
    }
    closedir(dir);

    pthread_t threads[NUM_THREADS];
    thread_data_t thread_data[NUM_THREADS];

    int files_per_thread = total_files / num_threads;
    for (int i = 0; i < num_threads; i++) {
        thread_data[i].path = path;
        thread_data[i].start = i * files_per_thread;
        thread_data[i].end = (i == num_threads - 1) ? total_files : (i + 1) * files_per_thread;
        pthread_create(&threads[i], NULL, list_directory_thread, (void *)&thread_data[i]);
    }

    for (int i = 0; i < num_threads; i++) {
        pthread_join(threads[i], NULL);
    }
}

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

    list_directory_multithreaded(argv[1], NUM_THREADS);
    return EXIT_SUCCESS;
}

4. 使用readdir_r

在某些系统上,readdir可能是线程不安全的。可以使用readdir_r来替代,它是线程安全的版本。

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

void list_directory_readdir_r(const char *path) {
    DIR *dir = opendir(path);
    if (dir == NULL) {
        perror("opendir");
        return;
    }

    struct dirent entry;
    struct dirent *current;
    while (readdir_r(dir, &entry, &current) == 0) {
        if (current->d_type == DT_REG) { // 只列出普通文件
            printf("%s\n", current->d_name);
        }
    }

    closedir(dir);
}

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

    list_directory_readdir_r(argv[1]);
    return EXIT_SUCCESS;
}

通过这些方法,你可以在CentOS中优化使用readdir的代码,提高目录遍历的效率。

0
看了该问题的人还看了