今天分析下利用 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