[技術] 在C中列出目錄與檔案

Written on 8:50 上午 by Yu Lai

一般在C中,我們可以使用opendir()與readdir()來列出目錄下所有的檔案。
以下是範例程式:

#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

main() {
DIR * dir;
struct dirent * ptr;
int i;
dir =opendir(“/etc/rc.d”);
while((ptr = readdir(dir))!=NULL) {
printf(“d_name: %s\n”,ptr->d_name);
}
closedir(dir);
}

配合struct dirent,定義如下:
struct dirent {
ino_t d_ino;
off_t d_off;
unsigned short int d_reclen;
unsigned char d_type;
char d_name[256];
};

d_ino 此目錄進入點的inode
d_off 目錄文件開頭至此目錄進入點的位移
d_reclen d_name的長度,不包含NULL字符
d_type d_name所指的檔案類型
d_name 檔名
其中unsigned cahr d_type;可以來判斷是子目錄或是一般的檔案。
但不知是我使用的uClibC的問題,沒實作到還怎樣,使用上一直有問題。

後來還是找到解決方法,方法有2種,分別如下:
1. 再使用一次readdir()來判斷回傳值,若回傳為NULL,即為檔案。
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

main() {
DIR * dir;
DIR * dir2;
struct dirent * ptr;
int i;
dir =opendir(“/etc/rc.d”);
while((ptr = readdir(dir))!=NULL) {
char pathname[100];
sprintf(pathname,"/etc/rc.d/%s", ptr->d_name);
if((dir2 = opendir(pathname))==NULL) {
printf("%s: file\n", ptr->d_name);
} else {
printf("%s: directory\n", ptr->d_name);
closedir(dir2);
}
}
closedir(dir);
}

2. 使用int stat(const char *file_name, struct stat *buf),
在struct stat其中的 st_mode 可以用來判斷是哪種檔案(也就是上面 d_type的 功用)。
為了方便,POSIX另外有定義幾個MACRO:
S_ISLNK(st_mode) : 是symbolic link
S_ISREG(st_mode) 一般檔案(regular file)
S_ISDIR(st_mode) 目錄(directory)
S_ISCHR(st_mode) 字元設備檔(char device)
S_ISBLK(st_mode) 區塊設備檔(block device)
S_ISSOCK(st_mode) local-domain socket
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

main() {
DIR * dir;
struct dirent * ptr;
int i;
dir =opendir(“/etc/rc.d”);
while((ptr = readdir(dir))!=NULL) {
char pathname[100];
struct stat buf;
sprintf(pathname,"/etc/rc.d/%s", ptr->d_name);
stat(pathname, &buf);
if(S_ISREG(buf.st_mode))
printf("%s: file\n", ptr->d_name);
else
printf("%s: directory\n", ptr->d_name);
}
closedir(dir);
}

If you enjoyed this post Subscribe to our feed

No Comment

張貼留言