星期四, 5月 18, 2006

readdir - read directory - and ..IsDirectory ?

上一次使用的ftw也是read directory,但是uClibc 沒有build進去(應該說uClibc有,但是toolchain SDK沒有包含進去)。
所以要用另一個:

struct dirent *readdir(DIR *dir)

argument : dir 是 由 opendir( )取得的目錄結構。
和open( )一樣,opendir( )開啟目錄後,會mantain一個目錄結構,讓你每次readdir( )讀取一筆目錄紀錄。

所以以下function會印出 目錄中所有檔案:

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

main()
{
DIR *dir;
struct dirent *ptr;


dir = opendir("/etc/init.d");
while( (ptr=readdir(dir))!=NULL)
printf("%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 cahr d_type;
chard d_name[256];
};

d_ino : entry inode
d_off : 目前讀取的offset
d_reclen : d_name[] 的長度,不含ending NULL
d_type : d_name 所指檔案的type
d_name : 檔名 (所以檔名最大是256?)
d_type的意義宣告在dirent.h
enum{
DT_UNKNOWN,
DT_FIFO,
DT_CHR,
DT_BLK,
DT_REG,
DT_LNK,
DT_SOCK,
DT_WHT
};
從define 中看到,好像不是bit field。使用時最好先測試一下 library 有沒有support。
如果沒有,就只有用 stat
 int stat(const char *file_name, struct stat *buf)
file_name 是檔名
buf 是傳回值,會將該檔案的各項資料放在struct stat的 buf 變數中 :(定義在 sys/stat.h)
struct stat
{
dev_t st_dev; //檔案的 設備編號
ino_t st_ino; // 檔案的inode
mode_t st_mode; // 檔案類型和權限
nlink_t st_nlink; // hard link 數
uid_t st_uid; // owner id
gid_t st_gid; // group id
dev_t st_rdev; // ? 也是設備編號?
.... 不寫了,,,,好多
};
其中 st_mode 可以用來判斷 是哪種檔案(也就是上面 d_type的 功用)。
為了方便,POSIX另外有定義幾個MACRO:
S_ISLNK(st_mode) : 是symbolic link ?
S_ISREG(st_mode) 一般檔案? (regulat file)
S_ISDIR(st_mode) 目錄?
S_ISCHR(st_mode) 字元檔 ?
S_ISBLK(st_mode) FIFO ?
S_ISSOCK(st_mode) socket ?

所以...要做到辨別directory 的功能,就要readdir和stat合在一起...
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>

main(int argc,char *argv[])
{
DIR *dir;
struct dirent *ptr;

dir=opendir(argv[1]);

while((ptr=readdir(dir))!=NULL){
struct stat buf;
char name[256];

printf("d_name: %s %x",ptr->d_name,ptr->l;d_type);
sprintf(name,"%s/%s",argv[1],ptr->d_name);
stat(name,&buf);
if(S_ISDIR(buf.st_mode))
printf("---directory\n");
else
printf("\n");
}



closedir(dir);
}

另一個,用opendir( )作目錄判斷,比較容易寫..(SDK的library 也是用這樣的方法..)
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>

main(int argc,char *argv[])
{
DIR *dir,*path;
struct dirent *ptr;

dir = opendir(argv[1]);

while((ptr=readdir(dir))!=NULL){
char pathname[100];

sprintf(pathname,"%s/%s",argv[1],ptr->d_name);
printf("%s",pathname);
if(opendir(pathname)==NULL)
printf("\n");
else
printf(" -- directory\n");
}

closedir(dir);
}
.

沒有留言:

張貼留言