在Linux中,readdir
函数是用于读取目录内容的系统调用。要实现目录监控,你可以结合readdir
和其他一些Linux功能,例如inotify
。下面是一个简单的示例,展示如何使用readdir
和inotify
来实现目录监控。
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;
}
readdir
和 inotify
你可以结合readdir
和inotify
来实现更复杂的目录监控功能。例如,当检测到目录变化时,重新读取目录内容并输出变化。
#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;
}
这个示例程序会在检测到目录变化时重新读取目录内容并输出变化。你可以根据需要扩展这个程序,添加更多的功能。