温馨提示×

readdir如何实现Linux目录同步

小樊
33
2025-11-23 16:12:01
栏目: 智能运维

readdir 是一个用于读取目录内容的函数,通常在 C 语言中使用。要实现 Linux 目录同步,你需要比较两个目录的内容,并根据需要复制、删除或重命名文件。以下是一个简单的示例,展示了如何使用 readdir 实现目录同步:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

void sync_directories(const char *dir1, const char *dir2);

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

    sync_directories(argv[1], argv[2]);
    return 0;
}

void sync_directories(const char *dir1, const char *dir2) {
    DIR *dp1 = opendir(dir1);
    DIR *dp2 = opendir(dir2);

    if (!dp1 || !dp2) {
        perror("opendir");
        return;
    }

    struct dirent *entry;
    while ((entry = readdir(dp1)) != NULL) {
        char path1[PATH_MAX], path2[PATH_MAX];
        snprintf(path1, sizeof(path1), "%s/%s", dir1, entry->d_name);
        snprintf(path2, sizeof(path2), "%s/%s", dir2, entry->d_name);

        struct stat st1, st2;
        if (stat(path1, &st1) == -1 || stat(path2, &st2) == -1) {
            perror("stat");
            continue;
        }

        if (S_ISDIR(st1.st_mode) && S_ISDIR(st2.st_mode)) {
            sync_directories(path1, path2);
        } else {
            if (access(path2, F_OK) == -1) {
                // File doesn't exist in dir2, copy it from dir1 to dir2
                FILE *src = fopen(path1, "rb");
                FILE *dst = fopen(path2, "wb");

                if (src && dst) {
                    char buffer[4096];
                    size_t n;
                    while ((n = fread(buffer, 1, sizeof(buffer), src)) > 0) {
                        fwrite(buffer, 1, n, dst);
                    }
                    fclose(src);
                    fclose(dst);
                } else {
                    perror("fopen");
                }
            } else if (memcmp(&st1, &st2, sizeof(st1)) != 0) {
                // Files are different, copy the updated file from dir1 to dir2
                remove(path2);
                FILE *src = fopen(path1, "rb");
                FILE *dst = fopen(path2, "wb");

                if (src && dst) {
                    char buffer[4096];
                    size_t n;
                    while ((n = fread(buffer, 1, sizeof(buffer), src)) > 0) {
                        fwrite(buffer, 1, n, dst);
                    }
                    fclose(src);
                    fclose(dst);
                } else {
                    perror("fopen");
                }
            }
        }
    }

    closedir(dp1);
    closedir(dp2);

    // Remove files in dir2 that don't exist in dir1
    dp1 = opendir(dir1);
    dp2 = opendir(dir2);

    while ((entry = readdir(dp2)) != NULL) {
        char path1[PATH_MAX], path2[PATH_MAX];
        snprintf(path1, sizeof(path1), "%s/%s", dir1, entry->d_name);
        snprintf(path2, sizeof(path2), "%s/%s", dir2, entry->d_name);

        struct stat st1, st2;
        if (stat(path1, &st1) == -1 || stat(path2, &st2) == -1) {
            perror("stat");
            continue;
        }

        if (S_ISDIR(st1.st_mode) && S_ISDIR(st2.st_mode)) {
            sync_directories(path1, path2);
        } else if (access(path1, F_OK) == -1) {
            remove(path2);
        }
    }

    closedir(dp1);
    closedir(dp2);
}

这个示例程序接受两个命令行参数,分别是源目录和目标目录。它会递归地比较这两个目录的内容,并确保它们保持同步。如果目标目录中缺少源目录中的文件,程序会将文件复制到目标目录。如果目标目录中的文件与源目录中的文件不同,程序会将更新后的文件复制到目标目录。最后,程序会删除目标目录中存在于源目录中但不存在的文件。

请注意,这个示例程序没有处理所有可能的错误情况,也没有实现删除和重命名操作。在实际应用中,你可能需要根据具体需求对其进行扩展和优化。

0