目录编程
- 前言
- 目录编程函数
- 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");
//如果存在多个路径信息
else
while(--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;}
}
运行结果图: