目录的读取
1. opendir() - 打开目录1.1 函数原型#includedirent.hDIR*opendir(constchar*name);DIR*fdopendir(intfd);// 使用文件描述符需配合open()函数使用1.2 参数说明name: 要打开的目录路径名可以是相对路径或绝对路径fd: 已打开目录的文件描述符仅用于fdopendir()1.3 返回值成功: 返回指向DIR结构体的指针目录流指针失败: 返回NULL并设置errno表示错误类型1.4 DIR结构体DIR是一个不透明数据类型用于表示一个打开的目录流。开发者通常不需要直接访问其内部成员只需将其作为句柄传递给其他目录操作函数。1.5 使用步骤包含头文件dirent.h调用opendir()打开目标目录检查返回值是否为NULL处理可能的错误将返回的DIR*指针保存供后续使用1.6 错误处理常见的错误情况包括ENOENT: 目录不存在EACCES: 权限不足ENOTDIR: 路径不是目录EMFILE: 进程打开文件数达到上限2. readdir() - 读取目录项2.1 函数原型#includedirent.hstructdirent*readdir(DIR*dirp);2.2 参数说明dirp: 由opendir()返回的目录流指针2.3 返回值成功: 返回指向struct dirent的指针表示目录中的一个条目目录结束: 返回NULL此时不设置errno出错: 返回NULL并设置errno2.4 struct dirent结构体structdirent{ino_td_ino;/* 索引节点号 */off_td_off;/* 目录文件中的偏移 */unsignedshortd_reclen;/* 记录长度 */unsignedchard_type;/* 文件类型 */chard_name[256];/* 文件名 */};重要成员说明d_name: 文件名以null结尾的字符串d_type: 文件类型标识符常用值包括DT_REG: 普通文件DT_DIR: 目录DT_LNK: 符号链接DT_UNKNOWN: 未知类型2.5 使用模式典型的目录遍历模式structdirent*entry;while((entryreaddir(dirp))!NULL){// 处理每个目录项printf(文件名: %s\n,entry-d_name);}2.6 注意事项readdir()不是线程安全的多线程环境应使用readdir_r()返回的struct dirent指针指向静态存储区每次调用会被覆盖特殊目录项.当前目录和..上级目录也会被读取3. closedir() - 关闭目录3.1 函数原型#includedirent.hintclosedir(DIR*dirp);3.2 参数说明dirp: 要关闭的目录流指针3.3 返回值成功: 返回0失败: 返回-1并设置errno3.4 重要性及时关闭目录流非常重要原因包括释放系统资源文件描述符确保目录内容变更能及时反映避免文件描述符泄漏4. 完整示例程序4.1 基本目录遍历#includestdio.h#includedirent.h#includeerrno.h#includestring.hintlist_directory(constchar*path){DIR*diropendir(path);if(dirNULL){fprintf(stderr,无法打开目录 %s: %s\n,path,strerror(errno));return-1;}printf(目录 %s 的内容:\n,path);printf(\n);structdirent*entry;intcount0;while((entryreaddir(dir))!NULL){// 跳过 . 和 .. 目录if(strcmp(entry-d_name,.)0||strcmp(entry-d_name,..)0){continue;}printf(%3d. %s,count,entry-d_name);// 根据文件类型添加标识switch(entry-d_type){caseDT_DIR:printf( [目录]);break;caseDT_REG:printf( [文件]);break;caseDT_LNK:printf( [链接]);break;default:printf( [其他]);}printf(\n);}printf(\n);printf(总计: %d 个项目\n,count);if(closedir(dir)-1){fprintf(stderr,关闭目录失败: %s\n,strerror(errno));return-1;}return0;}intmain(){constchar*test_dir.;if(list_directory(test_dir)0){printf(目录遍历完成\n);}else{printf(目录遍历失败\n);}return0;}4.2 按文件类型筛选#includestdio.h#includedirent.h#includestring.hvoidlist_files_by_type(constchar*path,unsignedchartype){DIR*diropendir(path);if(dirNULL)return;structdirent*entry;printf(类型 %d 的文件:\n,type);while((entryreaddir(dir))!NULL){if(entry-d_typetypestrcmp(entry-d_name,.)!0strcmp(entry-d_name,..)!0){printf( %s\n,entry-d_name);}}closedir(dir);}intmain(){printf(当前目录下的所有子目录:\n);list_files_by_type(.,DT_DIR);printf(\n当前目录下的所有普通文件:\n);list_files_by_type(.,DT_REG);return0;}