1. 程式人生 > >掃描dir目錄函式之scandir()

掃描dir目錄函式之scandir()

scandir: 讀取特定的目錄資料標頭檔案: dirent.h 函式定義: int scandir(const char *dir, struct dirent ***namelist, int (*select)(const struct dirent *), int (*compar)(const struct dirent**, const struct dirent**)); 

說明: scandir()會掃描引數dir指定的目錄檔案, 經由引數select指定的函式來挑選目錄結構至引數 namelist陣列中, 最後在呼叫引數compar指定的函式來排序namelist陣列中的目錄資料. 每次從目錄檔案中讀取一個目錄結構後便將此結構傳給引數select所指的函式, select函式若不想要將此目錄機構複製到 namelist陣列就返回0, 若select為空指標則代表選擇所有的目錄結構. scandir()會呼叫qsort()來排序資料, 引數compar則為qsort()的引數, 若是要排列目錄名稱字母則可使用alphasort(). 結構dirent定義請參考readdir(). 成功則返回複製到namelist陣列中的資料結構數目, 有錯誤發生則返回-1. ENOMEM表示核心記憶體不足.

其中 dirent原型為:

struct linux_dirent64 {
	u64		d_ino;
	s64		d_off;
	unsigned short	d_reclen;
	unsigned char	d_type;
	char		d_name[0];
};

測試一下該函式功能,新建一個資料夾“test”在裡面建若干檔案和資料夾 如圖:


編寫測試程式碼:

      #include <dirent.h>

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

           n = scandir(".", &namelist, NULL, alphasort);
           if (n < 0)
               perror("scandir");
           else {
               while (n--) {
                   printf("%s:%d\n", namelist[n]->d_name,namelist[n]->d_type);
                   free(namelist[n]);
               }
               free(namelist);
           }
       }

執行發現:

F5:0
F4:0
F3:0
F2:0
F1:0
D4:0
D3:0
D2:0
D1:0
..:0
.:0

說明namelist[n]->d_type對檔案型別支援還是不夠的,需要用stat函式繼續對其分析。

完整測試程式碼如下:

	struct dirent **namelist;
	struct stat tStat;
	int n;
	char strTmp[256];
	n = scandir("/prj/test/", &namelist, NULL, alphasort);
	if (n < 0)
		perror("scandir");
	else {
		while (n--) {

			snprintf(strTmp, 256, "%s/%s", "/prj/test/", namelist[n]->d_name);
			strTmp[255] = '\0';
			if ((stat(strTmp, &tStat) == 0))
            {
                  if(S_ISDIR(tStat.st_mode))
                  {
					printf("%s:is a dir\n", namelist[n]->d_name);
                  }
				  else if(S_ISREG(tStat.st_mode))
				  {
					printf("%s:is a file\n", namelist[n]->d_name);
				  }
				  else
				  {
					printf("%s:unknow2\n", namelist[n]->d_name);
				  }
				  	
            }
			free(namelist[n]);
		}
		free(namelist);
	}

此時列印資訊為:

F5:is a file
F4:is a file
F3:is a file
F2:is a file
F1:is a file
D4:is a dir
D3:is a dir
D2:is a dir
D1:is a dir
..:is a dir
.:is a dir

將該目錄下的檔案及目錄都識別出來了