【Linux系统编程】深入理解Linux目录扫描函数:scandir目录函数(按条件扫描目录

本文详细介绍了Linux系统中的目录扫描函数scandir,scandirat,以及排序函数alphasort和versionsort。讲解了它们的原型、参数、内存分配和返回值,是理解Linux系统编程的基础知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


深入理解Linux目录扫描函数:scandir, scandirat, alphasort, versionsort

引言

在Linux系统编程中,目录操作是一个常见的任务。本文将详细介绍scandir, scandirat, alphasort, 和 versionsort这几个用于目录扫描的函数。我们将从函数原型、参数说明、返回值,到内存分配等方面进行全面解析。

正如Bjarne Stroustrup在《The C++ Programming Language》中所说:“程序设计不仅仅是我们告诉计算机要做什么,更是关于我们如何组织复杂性。”

scandir函数详解

函数原型

#include <dirent.h>
int scandir(const char *dirp, struct dirent ***namelist,
              int (*filter)(const struct dirent *),
              int (*compar)(const struct dirent **, const struct dirent **));

参数说明

  • dirp:指定扫描的目录
  • namelist:struct dirent结构体类型的三级指针,用于获取该函数内部为存放返回结果的分配的动态内存,动态分配内存结构如图2-1所示.
  • filter:函数指针,指向过滤模式函数,当filter指针设置为NULL时,扫描dirp目录下的所有顶层文件.该函数有一个参数const struct dirent *是指在遍历过程中所遍历到的每一个子目录dirent,filter可以根据dirent的类型、名称等信息来判定当前的dirent是否为合法的子目录,合法则函数返回0,则该子目录的名称会被存储在namelist中;否则返回非0,则该子目录被过滤掉。
  • compar:函数指针,指向对遍历结果进行排序函数,alphasort函数和versionsort是经常用到的函数.
内存分配(Memory Allocation)

在这里插入图片描述

如图2-1所示,分配的内存包含两个部分:

  1. 一部分是struct dirent类型指针(一段连续内存,可看成指针数组),用于指向malloc分配用来存放目录信息内存地址,
  2. 另一部分是malloc分配struct dirent大小内存,存放遍历目录或文件的相关信息。
    若想获取目录相关信息,需要先获取指向该存放内存的指针,即图2-1中的strcut dirent *arr[N]指针数组地址。

返回值

scandir() 函数返回被选择的目录条数,或者如果出错返回 -1。

scandirat函数详解

函数原型

#include <fcntl.h>          /* Definition of AT_* constants */
#include <dirent.h>

int scandirat(int dirfd, const char *dirp, struct dirent ***namelist,
              int (*filter)(const struct dirent *),
              int (*compar)(const struct dirent **, const struct dirent **));

描述

scandirat()scandir()的扩展函数,主要区别在于第一个参数dirfd与第二个参数dirp
如果dirp是一个绝对路径的字符串,则函数无视参数dirfd,功能与scandir()一致。
如果dirp是一个相对路径的字符串,且参数dirfd的值是AT_FDCWD (#include <fcntl.h>),则表示从应用程序当前的工作路径拼接上dirp的相对路径所组成的绝对路径下去遍历;
当dirfd值不为AT_FDCWD时而是一个代替文件夹的file descriptor(参考dirfd(DIR*))时,则遍历的文件夹路径即为dirfd所指向的文件夹再拼接上dirp的相对路径所组成的绝对路径。

示例

#define _DEFAULT_SOURCE
#include <dirent.h>
 #include <stdio.h>
#include <stdlib.h>

int main(void)
       {
           struct dirent **namelist;
           int n;

           n = scandir(".", &namelist, NULL, alphasort);
           if (n == -1) {
               perror("scandir");
               exit(EXIT_FAILURE);
           }

           while (n--) {
               printf("%s\n", namelist[n]->d_name);
               free(namelist[n]);   //------------------------>①每访问完一条目录或文件信息,释放由malloc分配的用于存放该信息的动态内存
           }
           free(namelist);  //------------------------>②访问完指定目录下所有目录或文件信息内容,释放malloc分配的用于索引的指针数组内存

           exit(EXIT_SUCCESS);
       }

排序函数:alphasort和versionsort

alphasort

int alphasort(const struct dirent **a, const struct dirent **b);

alphasort()的实现是把dirent的名称用strcoll()进行比较。

versionsort

int versionsort(const struct dirent **a, const struct dirent **b);

versionsort()的实现是把dirent的名称用strverscmp()进行比较。

排序函数的不同点

  • alphasort()的实现是把dirent的名称用strcoll()进行比较,排序的结果是按ASCII编码的值由小到大排序。
  • versionsort()的实现是把dirent的名称strverscmp()进行比较,排序的结果是也按ASCII编码的值由小到大排序,不同的是支持对名称中按数字序号的排序。

返回值

alphasort() 和 versionsort() 函数返回一个小于、等于或大于零的整数,当第一个参数被认为是小于、等于或大于第二个参数时.

总结

在本文中,我们详细介绍了Linux系统中用于目录扫描的几个重要函数。这些函数不仅在文件系统操作中有广泛应用,也是理解Linux系统编程的关键。

正如古人所说:“探索无止境,学无止境。”在编程的世界里,每一个函数、每一个接口都是一个新世界,值得我们去探索和理解。

结语

在我们的编程学习之旅中,理解是我们迈向更高层次的重要一步。然而,掌握新技能、新理念,始终需要时间和坚持。从心理学的角度看,学习往往伴随着不断的试错和调整,这就像是我们的大脑在逐渐优化其解决问题的“算法”。

这就是为什么当我们遇到错误,我们应该将其视为学习和进步的机会,而不仅仅是困扰。通过理解和解决这些问题,我们不仅可以修复当前的代码,更可以提升我们的编程能力,防止在未来的项目中犯相同的错误。

我鼓励大家积极参与进来,不断提升自己的编程技术。无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力。


阅读我的CSDN主页,解锁更多精彩内容:泡沫的CSDN主页
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泡沫o0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值