今天分析下利用 scandir 函数获取文件列表。
函数原型
#include <dirent.h>
int scandir(const char *restrict dirp,
struct dirent ***restrict namelist,
int (*filter)(const struct dirent *),
int (*compar)(const struct dirent **,const struct dirent **));
scandir() 会扫描目录 dirp(不包括子目录),经由参数 filter 指定的函数来挑选符合条件的目录结构至参数namelist 数组中,最后再调用参数 compar 指定的函数来排序 namelist 数组中的目录数据。
每次从 dirp 中读取的目录结构后都会传递给 filter 进行过滤,若 filter 返回 0 则不会把该目录结构复制到 namelist 数组中。
若 filter 参数为 NULL,则选择所有目录到 namelist 组中。
scandir() 中会调用 qsort() 来对获取的目录列表进行排序,参数 compar 则为 qsort() 的参数,若是要把目录名称列表按照字母顺序排序则 compar 参数可使用 alphasort()。
返回值 : 返回获取到的目录项的数量。如果发生错误,则返回-1,并设置errno 以指示错误。
例子
#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]);
}
free(namelist);
exit(EXIT_SUCCESS);
}
运行结果
#./test
tdir
libc.c
libb.c
liba.c
gg.h
..
.
该结果是按照下标倒序显示的,也可以从下标 0 开始显示,这样就是按照字母排序的了。
使用 filter 参数进行过滤
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
int myfilter(const struct dirent *entry)
{
return strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..");
}
int main(void)
{
struct dirent **namelist;
int n;
n = scandir(".", &namelist, myfilter, alphasort);
if (n == -1) {
perror("scandir");
exit(EXIT_FAILURE);
}
while (n--) {
printf("%s\n", namelist[n]->d_name);
free(namelist[n]);
}
free(namelist);
exit(EXIT_SUCCESS);
}
运行结果
#./test
tdir
libc.c
libb.c
liba.c
gg.h
获取以 lib 开头的文件
int myfilter(const struct dirent *ent)
{
if(ent->d_type != DT_REG)
return 0;
return (strncmp(ent->d_name, "lib", 3) == 0);
}
运行结果如下:
#./test
libc.c
libb.c
liba.c