🔥博客简介:开了几个专栏,针对 Linux 和 rtos 系统,嵌入式开发和音视频开发,结合多年工作经验,跟大家分享交流嵌入式软硬件技术、音视频技术的干货。
✍️系列专栏:C/C++、Linux、rtos、嵌入式开发、流媒体、数据结构、网络协议、开源库、CMake、Makefile、架构设计模式等。
文章目录
一、概述
本文介绍Linux下目录操作相关的一些函数。
mkdir、rmdir、opendir、readdir、closedir、getcwd、chdir。
我们将从函数原型、头文件、函数作用、参数含义、返回值以及示例代码几个方面进行总结。
二、mkdir 创建目录
【1】函数原型
int mkdir(const char *path, mode_t mode);
【2】头文件
#include <sys/stat.h>
#include <sys/types.h>
【3】函数作用
用于创建一个新的目录,mkdir 函数本身只能创建单级目录。如果你想创建嵌套的目录subdir(例如 ./testdir/subdir,而testdir此时不存在),你需要逐级创建每个目录。
【4】参数含义
path: 要创建的目录的路径名,可以是绝对路径也可以是相对路径。
mode: 新目录的访问权限,一般为0777。
mode 参数由四个数字组成:
■ 第一个数字通常是 0
■ 第二个数字规定所有者的权限
■ 第三个数字规定所有者所属的用户组的权限
■ 第四个数字规定其他所有人的权限
可能的值(如需设置多个权限,请对下面的数字进行总计):
■ 1 = 执行权限
■ 2 = 写权限
■ 4 = 读权限
【5】返回值
函数返回值为0表示成功,-1表示失败。
【6】示例
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(int argc,char *argv[])
{
if(-1 == mkdir("test", 0777))
{
printf("创建目录失败\n");
}
else
{
printf("创建目录成功\n");
}
return 0;
}
编译运行
三、rmdir 删除目录
【1】函数原型
int rmdir(const char *path);
【2】头文件
#include <unistd.h>
【3】函数作用
用于删除目录(注意,只能删除空目录)。
如果要删除非空目录,可以使用递归方式删除目录中的所有文件和子目录,然后再删除空目录。
【4】参数含义
path: 要删除的目录路径,可以是绝对路径也可以是相对路径。
【5】返回值
函数返回值为0表示成功,-1表示失败。
【6】示例
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
if(-1 == rmdir("test"))
{
printf("删除目录失败\n");
}
else
{
printf("删除目录成功\n");
}
return 0;
}
编译运行
四、opendir 打开目录
【1】函数原型
DIR *opendir(const char *name);
【2】头文件
#include <sys/types.h>
#include <dirent.h>
【3】函数作用
该函数作用是打开指定的目录,并返回一个指向该目录的指针。
这样,程序便可以通过该指针对目录进行进一步的操作,比如遍历其中的文件和子目录
【4】参数含义
name:要打开的目录完全路径名,可以是绝对路径也可以是相对路径。
DIR:是一个结构体类型,用于表示打开的目录流。
【5】返回值
打开目录成功,返回目录流DIR结构体指针,打开目录失败,返回NULL置位错误码。
当opendir函数失败时,会设置errno全局变量来表示错误原因。
errno的值对应于特定的错误码,这些错误码定义在<errno.h>头文件中。
要获取对应错误码的字符串描述,可以使用strerror函数。
可以在调用opendir之后立即调用strerror(errno)来获取错误描述。
以下是一些常见的opendir函数可能返回的错误码及其含义:
返回值/错误代码 | 描述 |
---|---|
DIR* | 成功打开目录 |
NULL | 打开失败 |
EACCESS | 权限不足 |
EMFILE | 已达到进程可同时打开的文件数上限 |
ENFILE | 已达到系统可同时打开的文件数上限 |
ENOTDIR | 参数name非真正的目录 |
ENOENT | 参数name 指定的目录不存在,或是参数name 为一空字符串 |
ENOMEM | 核心内存不足 |
【6】示例
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main()
{
DIR *dir = opendir("./directory");
if (dir == NULL)
{
printf("opendir: %s\n", strerror(errno));
return 1;
}
closedir(dir);
return 0;
}
编译运行
五、readdir 读取目录
【1】函数原型
struct dirent *readdir(DIR * dir);
【2】头文件
#include <dirent.h>
#include <sys/types.h>
【3】函数作用
用于读取目录流。
【4】参数含义
dir: 是一个结构体类型,用于表示打开的目录流。
struct dirent *: 参数dir目录流的下个目录进入点
结构dirent 定义如下:
struct dirent
{
ino_t d_ino; // d_ino 此目录进入点的inode
ff_t d_off; // d_off 目录文件开头至此目录进入点的位移
signed short int d_reclen; // d_reclen d_name 的长度, 不包含NULL 字符
unsigned char d_type; // d_type d_name所指的文件类型
har d_name[256]; // d_name 文件名
};
【5】返回值
成功则返回参数dir目录流的下一个子条目(子目录或子文件),有错误发生或读取到目录文件尾则返回NULL。
返回值/错误代码 | 描述 |
---|---|
struct dirent* | 成功读取目录项 |
NULL | 读取失败或到达目录末尾 |
EBADF | 参数dir为无效的目录流 |
【6】示例
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(int argc, char*argv[])
{
DIR *dir = opendir("./");
if (dir == NULL)
{
printf("opendir: %s\n", strerror(errno));
return 1;
}
struct dirent *entry = NULL;
while ((entry = readdir(dir)) != NULL)
{
printf("Found file: %s\n", entry->d_name);
}
closedir(dir);
}
编译运行
六、closedir 关闭目录
【1】函数原型
int closedir(DIR * dir);
【2】头文件
#include<sys/types.h>
#include<dirent.h>
【3】函数作用
关闭dir所指的目录流
【4】参数含义
dir: 目录流的指针
【5】返回值
成功返回0;失败返回-1,错误原因存于errno 中。
【6】示例
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(int argc, char*argv[])
{
DIR *dir = opendir("./directory");
if (dir == NULL)
{
printf("opendir: %s\n", strerror(errno));
return 1;
}
struct dirent *entry = NULL;
while ((entry = readdir(dir)) != NULL)
{
printf("Found file: %s\n", entry->d_name);
}
int ret = closedir(dir);
if(ret != 0)
{
printf("opendir: %s\n", strerror(errno));
return 1;
}
return 0;
}
编译运行
【7】注意
目录文件作为一种文件,再打开必须关闭,否则会由于文件的进程打开文件过多而不能打开新的文件。
因此opendir函数和closedir函数同样是配对出现的。
七、getcwd 获取目录
【1】函数原型
char *getcwd(char *buf, size_t size);
【2】头文件
#include <unistd.h>
【3】函数作用
获取当前工作目录
【4】参数含义
buf:保存当前工作目录的字符串缓冲区。
size:缓存区的大小。
【5】返回值
如果调用成功返回当前目录,调用失败返回 NULL。
【6】示例
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
int main()
{
char buf[255];
if(getcwd(buf, sizeof(buf)) != NULL)
{
printf("Current working directory: %s\n", buf);
}
else
{
printf("getcwd: %s\n", strerror(errno));
return 1;
}
return 0;
}
编译运行
八、chdir 改变当前工作目录
【1】函数原型
int chdir(const char *path);
【2】头文件
#include <unistd.h>
【3】函数作用
用来将当前的工作目录改变成以参数path所指的目录
【4】参数含义
path: 目标目录,可以是绝对目录或相对目录
【5】返回值
执行成功则返回0,失败返回-1,错误码存于errno中。
【6】示例
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char buf[255];
if(getcwd(buf, sizeof(buf)) != NULL)
{
printf("directory: %s\n", buf);
}
else
{
printf("getcwd: %s\n", strerror(errno));
return 1;
}
int ret = chdir("/tmp");
if(ret != 0)
{
printf("chdir: %s\n", strerror(errno));
return 1;
}
if(getcwd(buf, sizeof(buf)) != NULL)
{
printf("directory: %s\n", buf);
}
else
{
printf("getcwd: %s\n", strerror(errno));
return 1;
}
return 0;
}
编译运行