在Ubuntu系统中,使用readdir函数读取目录时可能会遇到各种错误。以下是一些常见的错误及其处理技巧:
dirent结构体指针无效。dirent结构体指针为空。在调用readdir之前,确保你有读取目录的权限。
#include <sys/stat.h>
#include <unistd.h>
int has_read_permission(const char *path) {
    struct stat st;
    if (stat(path, &st) == -1) {
        perror("stat");
        return 0;
    }
    return S_ISDIR(st.st_mode) && access(path, R_OK);
}
在调用readdir之前,确保目录存在。
#include <sys/stat.h>
#include <unistd.h>
int directory_exists(const char *path) {
    struct stat st;
    return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
}
在遍历目录时,检查并处理符号链接。
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
void handle_symlink(const char *path) {
    char real_path[PATH_MAX];
    ssize_t len = readlink(path, real_path, sizeof(real_path) - 1);
    if (len != -1) {
        real_path[len] = '\0';
        printf("Symlink detected: %s -> %s\n", path, real_path);
    } else {
        perror("readlink");
    }
}
在读取目录项时,检查文件名长度。
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
void handle_long_filename(const char *name) {
    if (strlen(name) >= NAME_MAX) {
        fprintf(stderr, "Filename too long: %s\n", name);
    }
}
确保dirent结构体指针有效。
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
void safe_readdir(DIR *dirp) {
    struct dirent *entry;
    if ((entry = readdir(dirp)) == NULL) {
        if (errno == EINVAL) {
            fprintf(stderr, "Invalid dirent pointer\n");
        } else {
            perror("readdir");
        }
    } else {
        printf("Entry: %s\n", entry->d_name);
    }
}
以下是一个综合示例,展示了如何处理上述常见错误:
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
int main(const char *path) {
    if (!directory_exists(path)) {
        fprintf(stderr, "Directory does not exist: %s\n", path);
        return EXIT_FAILURE;
    }
    if (!has_read_permission(path)) {
        fprintf(stderr, "No read permission for directory: %s\n", path);
        return EXIT_FAILURE;
    }
    DIR *dirp = opendir(path);
    if (dirp == NULL) {
        perror("opendir");
        return EXIT_FAILURE;
    }
    struct dirent *entry;
    while ((entry = readdir(dirp)) != NULL) {
        handle_long_filename(entry->d_name);
        // Optionally handle symlinks
        handle_symlink(entry->d_name);
    }
    if (errno != 0) {
        perror("readdir");
    }
    closedir(dirp);
    return EXIT_SUCCESS;
}
通过这些技巧和示例代码,你可以更好地处理readdir函数在Ubuntu系统中可能遇到的各种错误。