• 嵌入式Linux系统编程 — 3.7 文件目录与处理


    目录

    1 文件目录

    1.1 文件目录简介

    1.2 目录存储形式

    2 创建和删除目录

    2.1 mkdir创建目录

    2.2 rmdir删除空目录

    3 opendir打开、 readdir读取以及closedir关闭目录

    3.1 打开文件 opendir

    3.2 读取目录 readdir

    3.3 重置目录起点rewinddir

    3.4 关闭目录 closedir

    3.4 示例程序 

    4 进程的当前工作目录 

    4.1 获取进程的当前工作目录getcwd

    4.2 改变当前工作目录chdir()和 fchdir()

    5 删除文件

    5.1 unlink 函数删除文件

    5.2 remove 函数删除文件

    5 文件重命名renme


    1 文件目录

    1.1 文件目录简介

    在Linux系统中,文件目录(也常称为文件夹)是一种特殊的文件,它用于组织和管理文件系统中的文件和子目录。目录本身也被视为文件,但是它们具有一些特殊的属性和操作方式,不同于普通文件。

    在 Linux 系统下,会有一些专门的系统调用或 C 库函数用于对文件夹进行操作,譬如:打开、创建文件夹、删除文件夹、读取文件夹以及遍历文件夹中的文件等。

    1.2 目录存储形式

    目录在文件系统中的存储方式与常规文件类似,常规文件包括了 inode 节点以及文件内容数据存储块(block);但对于目录来说, 其存储形式则是由 inode 节点和目录块所构成,目录块当中记录了有哪些文件组织在这个目录下,记录它们的文件名以及对应的 inode 编号。其存储形式如下图所示:

    目录块当中有多个目录项(或叫目录条目) ,每一个目录项(或目录条目) 都会对应到该目录下的某一个文件,目录项当中记录了该文件的文件名以及它的 inode 节点编号,所以通过目录的目录块便可以遍历找到该目录下的所有文件以及所对应的 inode 节点。

    2 创建和删除目录

    2.1 mkdir创建目录

    mkdir 函数是C语言标准库中的一个函数,用于在文件系统中创建一个新的目录。这个函数的原型如下:

    1. #include
    2. int mkdir(const char *pathname, mode_t mode);
    • pathname指向一个以null结尾的字符串,指定要创建的目录的路径。
    • mode用于设置新目录的权限。这个值通常使用S_IRWXU(所有者读、写、执行权限) | S_IRWXG(组读、写、执行权限) | S_IRWXO(其他用户读、写、执行权限)的组合来定义。

    下面是一个使用命令行参数来创建目录的示例程序

    1. #include
    2. #include
    3. #include
    4. #include
    5. int main(int argc, char *argv[])
    6. {
    7. // 检查是否提供了目录名作为命令行参数
    8. if (argc != 2) {
    9. fprintf(stderr, "Usage: %s directory_name\n", argv[0]);
    10. return EXIT_FAILURE;
    11. }
    12. const char *dir = argv[1]; // 命令行参数作为目录名
    13. mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; // 所有者、组和其他用户都有读、写、执行权限
    14. if (mkdir(dir, mode) == -1) {
    15. if (errno == EEXIST) {
    16. printf("Directory '%s' already exists.\n", dir);
    17. } else {
    18. perror("mkdir failed"); // perror函数会打印错误信息
    19. }
    20. return errno;
    21. }
    22. printf("Directory '%s' created successfully\n", dir);
    23. return 0;
    24. }

    程序在运行时提供一个参数,即目录名。如果用户提供了正确的参数数量,程序将尝试创建一个具有指定权限的目录。如果目录创建成功,程序将打印一条成功消息。如果目录已经存在,程序将打印一条相应的消息。如果发生其他错误,perror 函数将打印错误信息。程序运行结果如下:

    2.2 rmdir删除空目录

    rmdir 函数是C语言标准库中用于删除空目录的函数。如果目录不为空,rmdir 函数将失败。以下是 rmdir 函数的原型:

    1. #include
    2. int rmdir(const char *pathname);
    • pathname:指向一个以null结尾的字符串,指定要删除的目录的路径。

     下面是一个使用 main 函数和命令行参数来删除目录的示例程序:

    1. #include
    2. #include
    3. #include
    4. #include
    5. int main(int argc, char *argv[])
    6. {
    7. // 检查是否提供了目录名作为命令行参数
    8. if (argc != 2) {
    9. fprintf(stderr, "Usage: %s directory_name\n", argv[0]);
    10. return EXIT_FAILURE;
    11. }
    12. const char *dir = argv[1]; // 命令行参数作为目录名
    13. if (rmdir(dir) == -1) {
    14. if (errno == ENOTEMPTY) {
    15. printf("Directory '%s' is not empty.\n", dir);
    16. } else {
    17. perror("rmdir failed"); // perror函数会打印错误信息
    18. }
    19. return errno;
    20. }
    21. printf("Directory '%s' removed successfully\n", dir);
    22. return 0;
    23. }

    程序在运行时提供一个参数,即要删除的目录名。如果提供了正确的参数数量,程序将尝试删除该目录。如果目录删除成功,程序将打印一条成功消息。如果目录不为空,程序将打印一条相应的消息。

    3 opendir打开、 readdir读取以及closedir关闭目录

    3.1 打开文件 opendir

    opendir()函数用于打开一个目录,并返回指向该目录的句柄,供后续操作使用。 Opendir 是一个 C 库函数, opendir()函数原型如下所示:

    1. #include
    2. #include
    3. DIR *opendir(const char *name);
    • name: 指定需要打开的目录路径名,可以是绝对路径,也可以是相对路径。
    • 返回值: 成功将返回指向该目录的句柄,一个 DIR 指针(其实质是一个结构体指针),其作用类似于open函数返回的文件描述符fd,后续对该目录的操作需要使用该DIR指针变量;若调用失败,则返回NULL。

    3.2 读取目录 readdir

    readdir()用于读取目录,获取目录下所有文件的名称以及对应 inode 号。readdir()是一个 C 库函数(事实上 Linux 系统还提供了一个 readdir 系统调用),其函数原型如下所示:

    1. #include
    2. struct dirent *readdir(DIR *dirp);

    dirp: 目录句柄 DIR 指针。
    返回值: 返回一个指向 struct dirent 结构体的指针, 该结构体表示 dirp 指向的目录流中的下一个目录条目。在到达目录流的末尾或发生错误时,它返回 NULL。

    每调用一次 readdir(),就会从 drip 所指向的目录流中读取下一条目录项(目录条目),并返回 struct dirent结构体指针(struct dirent 结构体记录了文件的 inode 编号和文件名等信息)。

    当使用 opendir()打开目录时,目录流将指向了目录列表的头部(0) ,使用 readdir()读取一条目录条目之后,目录流将会向后移动、指向下一个目录条目。这其实跟 open()类似, 当使用 open()打开文件的时候,文件位置偏移量默认指向了文件头部,当使用 read()或 write()进行读写时,文件偏移量会自动向后移动。

    3.3 重置目录起点rewinddir

    rewinddir()是 C 库函数,可将目录流重置为目录起点, 以便对 readdir()的下一次调用将从目录列表中的第一个文件开始。 rewinddir 函数原型如下所示:

    1. #include
    2. #include
    3. void rewinddir(DIR *dirp);
    • dirp: 目录句柄

    3.4 关闭目录 closedir

    closedir()函数用于关闭处于打开状态的目录,同时释放它所使用的资源,其函数原型如下所示:

    1. #include
    2. #include
    3. int closedir(DIR *dirp);

    3.4 示例程序 

    下面的示例程序接收命令行参数作为目录名,然后列出该目录下的所有文件和目录项:

    1. #include
    2. #include
    3. #include
    4. #include
    5. int main(int argc, char *argv[])
    6. {
    7. // 检查是否提供了目录名作为命令行参数
    8. if (argc != 2) {
    9. fprintf(stderr, "Usage: %s directory_name\n", argv[0]);
    10. return EXIT_FAILURE;
    11. }
    12. const char *dir_name = argv[1]; // 命令行参数作为目录名
    13. DIR *dir_ptr = NULL;
    14. struct dirent *entry;
    15. // 打开目录以供读取
    16. dir_ptr = opendir(dir_name);
    17. if (dir_ptr == NULL) {
    18. perror("opendir failed"); // perror函数会打印错误信息
    19. return errno;
    20. }
    21. // 读取目录中的所有条目
    22. while ((entry = readdir(dir_ptr)) != NULL) {
    23. printf("%s\n", entry->d_name); // 打印文件或目录名
    24. }
    25. // 关闭目录流
    26. if (closedir(dir_ptr) == -1) {
    27. perror("closedir failed");
    28. return errno;
    29. }
    30. return 0;
    31. }

    在这个示例中,程序首先检查命令行参数的数量是否正确。如果正确,它将尝试打开指定的目录。如果目录成功打开,程序将使用 readdir 函数遍历目录中的所有条目,并打印每个条目的名称。最后,使用 closedir 函数关闭目录流。程序运行结果如下:

    4 进程的当前工作目录 

    4.1 获取进程的当前工作目录getcwd

    getcwd 函数是 POSIX 标准定义的用于获取当前工作目录的完整路径的函数。以下是 getcwd 函数的原型:

    1. #include
    2. char *getcwd(char *buf, size_t size);
    • buf:指向一个字符数组的指针,用于存储当前工作目录的路径。如果为 NULLgetcwd 将分配一个足够大的缓冲区。
    • size:缓冲区的大小。

    下面是使用 getcwd 函数的示例程序,该程序将打印当前工作目录的路径:

    1. #include
    2. #include
    3. #include
    4. #include
    5. int main(void) {
    6. char *buffer;
    7. size_t bufferSize = 1024;
    8. // 尝试获取当前工作目录
    9. buffer = getcwd(NULL, bufferSize); // 使用 NULL 让 getcwd 分配缓冲区
    10. if (buffer == NULL) {
    11. perror("getcwd failed"); // perror 函数会打印错误信息
    12. return errno;
    13. }
    14. // 打印当前工作目录
    15. printf("Current working directory: %s\n", buffer);
    16. // 释放 getcwd 分配的缓冲区
    17. free(buffer);
    18. return 0;
    19. }

    getcwd 被用来获取当前工作目录的路径,并将结果存储在 buffer 中。如果 getcwd 成功,程序将打印当前工作目录的路径。如果失败,perror 函数将打印错误信息。最后,如果 getcwd 分配了缓冲区,程序将使用 free 函数释放它。运行结果如下:

    4.2 改变当前工作目录chdir()和 fchdir()

    chdir()fchdir() 是两个用于更改当前工作目录的函数,两个函数的原型如下:

    1. #include
    2. int chdir(const char *path);
    • path:指向以null结尾的字符串的指针,指定要切换到的目录的路径。
    1. #include
    2. int fchdir(int fd);
    • fd:文件描述符,指向一个目录的文件描述符。

    5 删除文件

    5.1 unlink 函数删除文件

    unlink 函数用于删除文件的函数,以下是 unlink 函数的原型:

    1. #include
    2. int unlink(const char *pathname);
    • pathname:指向以null结尾的字符串的指针,指定要删除的文件的路径。

    下面是一个使用 unlink 函数删除文件的示例程序,该程序接收命令行参数作为要删除的文件名:

    1. #include
    2. #include
    3. #include
    4. #include
    5. int main(int argc, char *argv[]) {
    6. // 检查是否提供了文件名作为命令行参数
    7. if (argc != 2) {
    8. fprintf(stderr, "Usage: %s filename\n", argv[0]);
    9. return EXIT_FAILURE;
    10. }
    11. const char *filename = argv[1]; // 命令行参数作为文件名
    12. // 尝试删除文件
    13. if (unlink(filename) == -1) {
    14. perror("unlink failed"); // perror 函数会打印错误信息
    15. return errno;
    16. }
    17. printf("File '%s' has been successfully deleted\n", filename);
    18. return 0;
    19. }

    程序首先检查命令行参数的数量是否正确。如果正确,它将尝试删除指定的文件。如果文件删除成功,程序将打印一条成功消息。如果删除失败,perror 函数将打印错误信息。运行结果如下,从测试结果可看到,只能删除文件,不能删除文件夹

    5.2 remove 函数删除文件

    remove 函数是C标准库中的一个函数,它可以删除文件或空目录。与unlink不同,remove可以删除空目录,但不能删除非空目录。以下是remove函数的原型:

    1. #include
    2. int remove(const char *filename);
    • filename:指向以null结尾的字符串的指针,指定要删除的文件或目录的路径。

    示例程序将5.1中的unlink变为remove ​​​​​​​,运行结果如下,从运行结果可以看到,remove可以删除目录。

    5 文件重命名renme

    rename 函数用于重命名文件或目录。以下是 rename 函数的原型:

    1. #include
    2. int rename(const char *oldpath, const char *newpath);
    • oldpath:指向以null结尾的字符串的指针,指定要重命名的文件或目录的当前名称。
    • newpath:指向以null结尾的字符串的指针,指定新的名称。

    下面是 rename 函数重命名文件的示例程序,程序接收两个命令行参数:oldpathnewpath: 

    程序首先检查命令行参数的数量是否正确。如果正确,它将尝试将文件或目录从 oldpath 重命名为 newpath。如果重命名成功,程序将打印一条成功消息。如果重命名失败,perror 函数将打印错误信息。

  • 相关阅读:
    SpringMVC之国际化&上传&下载
    ACM笔记
    1.13 函数(一)(Python)
    基于springboot+vue的在线购房(房屋租赁)系统
    Asp .NetCore 从数据库加载配置(一)
    K8s如何快速部署Prometheus
    嵌入式软件调试的发展历程
    自动驾驶:2022 apollo day 观后感(三)
    Json 基于类 Newtonsoft.Json.Linq.JToken 的应用简介【C# 基础】
    生产质量管理系统有哪些功能?
  • 原文地址:https://blog.csdn.net/qq_41921826/article/details/139549036