目录编程
- 前言
- 目录编程函数
- mkdir 创建目录
- rmdir 删除目录
- opendir 打开目录
- readdir 读取目录
- stat 获取文件信息
- chdir 跳转目录
- closedir 关闭目录
- 判断文件类型的宏
- 遍历指定目录及子目录下所有.c文件示例
前言
相较于文件编程,目录编程也有一套自己的函数,可以进行创建、打开、读取等目录操作。
在日常中使用较多的是遍历目录,比如音乐播放器检测本地音乐、视频播放器打开指定目录下的视频等等。
目录编程函数
mkdir 创建目录
头文件:
#include <sys/stat.h>
#include <sys/types.h>
函数原型:int mkdir(const char *pathname, mode_t mode);
参数介绍:
pathname:要创建的文件的 路径+名字
mode:创建的文件的权限(与umask相关)
返回值:创建成功返回0,失败返回-1。
mkdir ( "./1.txt" , 0644 );
rmdir 删除目录
头文件:
#include <unistd.h>
函数原型:int rmdir(const char *pathname);
参数介绍:
pathname:要删除的文件的 路径+名字
返回值:删除成功返回0,失败返回-1。
rmdir ( "./1.txt" );
opendir 打开目录
头文件:
#include<sys/types.h>
#include<dirent.h>
函数原型:DIR * opendir(const char * name);
参数介绍:
name:要打开的目录的 路径+名字
返回值:如果成功打开目录,则返回一个指向该目录的目录流指针,如果失败,则返回NULL。
DIR * dir = opendir ( "/home/wwz" );
readdir 读取目录
头文件:
#include<sys/types.h>
#include<dirent.h>
函数原型:struct dirent * readdir(DIR * dir);
参数介绍:
dir:opendir返回的目录流指针
返回值:成功则返回下个目录进入点. 有错误发生或读取到目录文件尾则返回NULL。
struct dirent * readpos = readdir ( dir );
stat 获取文件信息
头文件:
#include<sys/types.h>
#include<unistd.h>
函数原型:int stat(const char * file_name,struct stat *buf);
参数介绍:
file_name:要获取信息的文件 路径+名字
buf:保存文件信息的stat结构体容器
返回值:执行成功则返回0,失败返回-1,错误代码存于errno。
//初始化结构体struct dirent * readpos = NULL;//目录流指针//打开目录DIR * dir = opendir ( "/home/wwz" );//当该文件能读取信息时while ( (readpos = readdir( dir )) != NULL ){char path[512] = {0};struct stat statpos;//文件信息结构体sprintf( path , "%s%s" , "/home/wwz" , readpos->d_name );//获取文件信息if( !stat ( path , &statpos ) ){printf(```结构体成员```)}}
while循环能遍历打印目录下的所有文件
chdir 跳转目录
头文件:
#include<unistd.h>
函数原型:int chdir(const char * path);
参数介绍:
path:要跳转的目录 路径+名字
返回值:执行成功则返回 0,失败返回-1,errno 为错误代码。
chdir ( "/home/root/" );
closedir 关闭目录
头文件:
#include<sys/types.h>
#include<dirent.h>
函数原型:int closedir(DIR *dir);
参数介绍:
dir:要跳转关闭的目录的目录流指针
返回值:关闭成功则返回 0,失败返回-1,errno 为错误代码。
closedir ( dir );//如果将该函数与打开目录函数置于获取文件信息//示例代码中并加入是否为文件判断//就可以递归的遍历所有文件//在文档末尾我会提供一个查看目录下//以及子目录下所有.c文件的例子
判断文件类型的宏
当然想要实现遍历指定目录及子目录下所有.c文件还要判断文件的类型,<stat.h>中提供了相应的宏定义。
带参宏 | 无参宏 | 解释 |
---|---|---|
S_ISLNK(mode) | S_ISLNK | 判断是否为链接文件类型 |
S_ISREG(mode) | S_ISREG | 判断是否为普通文件类型 |
S_ISDIR(mode) | S_ISDIR | 判断是否为目录类型 |
S_ISCHR(mode) | S_ISCHR | 判断是否为字符型设备类型 |
S_ISBLK(mode) | S_ISBLK | 判断是否为块设备类型 |
S_ISFIFO(mode) | S_ISFIFO | 判断是否为命名管道类型 |
S_ISSOCK(mode) | S_ISSOCK | 判断是否为套接字类型 |
遍历指定目录及子目录下所有.c文件示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>void isDir(char *dir);
void isFile(char *name);int main(int argc,char *argv[])
{//路径信息通过argv传输if(argc == 1)printf("运行时请输入至少一个路径\n");//如果存在多个路径信息elsewhile(--argc)//先判断是不是文件,如果是文件,否则就打开目录isFile(*++argv);return 0;
}void isFile(char * name)
{struct stat buff = {0};//或取文件信息int ret = stat(name,&buff);if(ret == -1){perror("stat");exit(1);}if(S_ISDIR(buff.st_mode))//如果是目录isDir(name);else if(S_ISREG(buff.st_mode))//如果是普通文件{char *tempFileName = name;//tempFileName为指针,可以进行偏移操作//下面的 tempFileName + strlen(name)-2 就是将指针偏移到末尾的 .c 的位置if( strncmp ( tempFileName + strlen(name)-2 , ".c" , 2) == 0)printf( "%s\n" , tempFileName );}
}void isDir(char *dir)
{struct dirent *sdp;char path[256];//打开目录DIR *dp = opendir(dir);if( dp == NULL ){perror("opendir");return;}//遍历目录while( (sdp = readdir(dp)) != NULL){//防止跳转当前上级目录 造成死循环if(strcmp(sdp->d_name,".")==0||strcmp(sdp->d_name,"..")==0)continue;//或取文件信息sprintf(path,"%s/%s",dir,sdp->d_name);isFile(path);}//关闭文件int ret = closedir(dp);if(ret == -1){perror("closedir");return;}
}
运行结果图: