C++11及更早版本如何获取目录下子项的类型与权限
实现方案
你可以通过两种兼容C++11之前环境的标准POSIX C接口实现需求:
1. 直接通过struct dirent的d_type字段快速判断文件类型
struct dirent内置的d_type字段可直接返回子项类型,常见取值如下:
DT_REG:普通文件DT_DIR:目录DT_LNK:软链接DT_CHR:字符设备DT_BLK:块设备DT_FIFO:管道DT_SOCK:套接字
注意:该字段依赖文件系统支持,部分老旧文件系统可能返回DT_UNKNOWN,这种情况需要用stat接口做兼容判断。
2. 通过stat系统调用获取完整的类型和权限信息
这是兼容性最好的方案,不仅能准确获取文件类型,还能拿到所有者、所属组、其他用户的读/写/执行权限,需要引入头文件sys/stat.h和sys/types.h,调用stat传入文件路径后,从返回的struct stat结构体的st_mode字段解析即可:
类型判断宏(针对st_mode):
S_ISREG(st_mode):是否为普通文件S_ISDIR(st_mode):是否为目录S_ISLNK(st_mode):是否为软链接S_ISCHR(st_mode):是否为字符设备S_ISBLK(st_mode):是否为块设备S_ISFIFO(st_mode):是否为管道S_ISSOCK(st_mode):是否为套接字
权限判断宏(针对st_mode):
所有者权限:
S_IRUSR:所有者读权限S_IWUSR:所有者写权限S_IXUSR:所有者执行权限
所属组权限:S_IRGRP:所属组读权限S_IWGRP:所属组写权限S_IXGRP:所属组执行权限
其他用户权限:S_IROTH:其他用户读权限S_IWOTH:其他用户写权限S_IXOTH:其他用户执行权限
完整可运行代码
#include <stdio.h> #include <dirent.h> #include <sys/stat.h> #include <sys/types.h> #include <string.h> int main(void) { struct dirent *de; DIR *dr = opendir("."); struct stat st; char path_buf[1024]; // 存储拼接后的文件路径 if (dr == NULL) { printf("Could not open current directory" ); return 0; } while ((de = readdir(dr)) != NULL) { // 跳过.和..两个特殊目录 if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; // 拼接完整路径,stat需要完整路径才能正确识别 snprintf(path_buf, sizeof(path_buf), "./%s", de->d_name); if (stat(path_buf, &st) != 0) { printf("%s : 获取信息失败\n", de->d_name); continue; } // 打印文件名 printf("名称:%s\n", de->d_name); // 打印类型 printf("类型:"); if (S_ISREG(st.st_mode)) printf("普通文件\n"); else if (S_ISDIR(st.st_mode)) printf("目录\n"); else if (S_ISLNK(st.st_mode)) printf("软链接\n"); else printf("其他类型\n"); // 打印所有者权限 printf("所有者权限:"); printf("%c", (st.st_mode & S_IRUSR) ? 'r' : '-'); printf("%c", (st.st_mode & S_IWUSR) ? 'w' : '-'); printf("%c\n", (st.st_mode & S_IXUSR) ? 'x' : '-'); printf("------------------------\n"); } closedir(dr); return 0; }
注意事项
- 如果你需要读取软链接本身的属性而非指向的目标文件属性,将
stat替换为lstat即可 - 所有用到的接口都属于POSIX标准C接口,完全兼容C++11之前的编译环境
内容的提问来源于stack exchange,提问作者Adam Lee
相关产品推荐
相关产品推荐

