linux

Linux readdir如何实现目录监控

小樊
33
2025-05-18 19:44:57
栏目: 智能运维

在Linux中,readdir函数是用于读取目录内容的系统调用。要实现目录监控,你可以结合readdir和其他一些Linux功能,例如inotify。下面是一个简单的示例,展示如何使用readdirinotify来实现目录监控。

使用 readdir 读取目录内容

首先,我们来看一个简单的例子,展示如何使用readdir读取目录的内容:

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

int main(int argc, char *argv[]) {
    DIR *dir;
    struct dirent *entry;

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

    dir = opendir(argv[1]);
    if (dir == NULL) {
        perror("opendir");
        return EXIT_FAILURE;
    }

    while ((entry = readdir(dir)) != NULL) {
        printf("%s
", entry->d_name);
    }

    closedir(dir);
    return EXIT_SUCCESS;
}

使用 inotify 监控目录

inotify 是Linux内核提供的一种机制,用于监控文件系统事件。我们可以使用inotify来监控目录的变化,并在变化发生时读取目录内容。

下面是一个简单的示例,展示如何使用inotify监控目录的变化:

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

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

int main(int argc, char *argv[]) {
    int length, i = 0;
    int fd;
    int wd;
    char buffer[BUF_LEN];

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

    fd = inotify_init();
    if (fd < 0) {
        perror("inotify_init");
        return EXIT_FAILURE;
    }

    wd = inotify_add_watch(fd, argv[1], IN_MODIFY | IN_CREATE | IN_DELETE);
    if (wd < 0) {
        perror("inotify_add_watch");
        close(fd);
        return EXIT_FAILURE;
    }

    printf("Monitoring directory %s for changes...
", argv[1]);

    while (1) {
        length = read(fd, buffer, BUF_LEN);
        if (length < 0) {
            perror("read");
            break;
        }

        while (i < length) {
            struct inotify_event *event = (struct inotify_event *) &buffer[i];
            if (event->len) {
                if (event->mask & IN_CREATE) {
                    printf("File %s created.
", event->name);
                } else if (event->mask & IN_DELETE) {
                    printf("File %s deleted.
", event->name);
                } else if (event->mask & IN_MODIFY) {
                    printf("File %s modified.
", event->name);
                }
            }
            i += EVENT_SIZE + event->len;
        }
        i = 0;
    }

    (void) inotify_rm_watch(fd, wd);
    (void) close(fd);

    return EXIT_SUCCESS;
}

结合 readdirinotify

你可以结合readdirinotify来实现更复杂的目录监控功能。例如,当检测到目录变化时,重新读取目录内容并输出变化。

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

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

void read_directory(const char *path) {
    DIR *dir;
    struct dirent *entry;

    dir = opendir(path);
    if (dir == NULL) {
        perror("opendir");
        return;
    }

    while ((entry = readdir(dir)) != NULL) {
        printf("%s
", entry->d_name);
    }

    closedir(dir);
}

int main(int argc, char *argv[]) {
    int length, i = 0;
    int fd;
    int wd;
    char buffer[BUF_LEN];

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

    fd = inotify_init();
    if (fd < 0) {
        perror("inotify_init");
        return EXIT_FAILURE;
    }

    wd = inotify_add_watch(fd, argv[1], IN_MODIFY | IN_CREATE | IN_DELETE);
    if (wd < 0) {
        perror("inotify_add_watch");
        close(fd);
        return EXIT_FAILURE;
    }

    printf("Monitoring directory %s for changes...
", argv[1]);

    while (1) {
        length = read(fd, buffer, BUF_LEN);
        if (length < 0) {
            perror("read");
            break;
        }

        while (i < length) {
            struct inotify_event *event = (struct inotify_event *) &buffer[i];
            if (event->len) {
                printf("Event type: %d
", event->mask);
                if (event->mask & IN_CREATE) {
                    printf("File %s created.
", event->name);
                } else if (event->mask & IN_DELETE) {
                    printf("File %s deleted.
", event->name);
                } else if (event->mask & IN_MODIFY) {
                    printf("File %s modified.
", event->name);
                }
                // Re-read the directory after an event
                read_directory(argv[1]);
            }
            i += EVENT_SIZE + event->len;
        }
        i = 0;
    }

    (void) inotify_rm_watch(fd, wd);
    (void) close(fd);

    return EXIT_SUCCESS;
}

这个示例程序会在检测到目录变化时重新读取目录内容并输出变化。你可以根据需要扩展这个程序,添加更多的功能。

0
看了该问题的人还看了