LINUX下歷遍目錄的方法一般是這樣的
打開目錄-》讀取-》關閉目錄
相關函數是
opendir -> readdir -> closedir
#include <dirent.h>
DIR *opendir(const char *dirname);
struct dirent *readdir(DIR *dirp);
int closedir(DIR *dirp);
好了,三個函數都出來了,原型就是上面。
opendir用於打開目錄,是類似於流的那種方式,返回一個指向DIR結構體的指針,參數*dirname是一個字符數組或者字符串常量;
readdir函數用於讀取目錄,只有一個參數,就是opendir返回的結構體指針,或者叫句柄更容易理解些吧。這個函數也返回一個結構體指針 dirent *;
DIR結構體定義
struct __dirstream
{
void *__fd;
char *__data;
int __entry_data;
char *__ptr;
int __entry_ptr;
size_t __allocation;
size_t __size;
__libc_lock_define (, __lock)
};
typedef struct __dirstream DIR;
dirent的結構如下定義
struct dirent
{
long d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name [NAME_MAX+1];
}
結構體中
- d_ino存放的是該文件的索引節點號inode;
- d_off 是文件在目錄中的編移,具體是什麼意思也不是很明白,很少用到它,
- 基本上就是用到d_name
- short d_reclen是這個文件的長度,需要注意的是這裏的長度並不是指文件大小,因爲大小和長度是兩回回事了,你可以用lseek將文件長度移得很長,但大小其實還是那麼大。
- 最後一個元素就是我們要的了,文件名稱。
通過readdir函數讀取到的文件名存儲在結構體dirent的d_name成員中,而函數
int stat(const char *file_name, struct stat *buf);的作用就是獲取文件名爲d_name的文件的詳細信息,存儲在stat結構體中。以下爲stat結構體的定義:
struct stat {
mode_t st_mode; //文件訪問權限
ino_t st_ino; //索引節點號
dev_t st_dev; //文件使用的設備號
dev_t st_rdev; //設備文件的設備號
nlink_t st_nlink; //文件的硬連接數
uid_t st_uid; //所有者用戶識別號
gid_t st_gid; //組識別號
off_t st_size; //以字節爲單位的文件容量
time_t st_atime; //最後一次訪問該文件的時間
time_t st_mtime; //最後一次修改該文件的時間
time_t st_ctime; //最後一次改變該文件狀態的時間
blksize_t st_blksize; //包含該文件的磁盤塊的大小
blkcnt_t st_blocks; //該文件所佔的磁盤塊
};
這個記錄的信息就很詳細了吧.
最後,總結一下,想要獲取某目錄下(比如a目下)b文件的詳細信息,我們應該怎樣做?
- 首先,我們使用opendir函數打開目錄a,返回指向目錄a的DIR結構體c。
- 接着,我們調用readdir( c)函數讀取目錄a下所有文件(包括目錄),返回指向目錄a下所有文件的dirent結構體d。
- 然後,我們遍歷d,調用stat(d->name,stat *e)來獲取每個文件的詳細信息,存儲在stat結構體e中。
總體就是這樣一種逐步細化的過程,在這一過程中,三種結構體扮演着不同的角色。
實例
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>
void print_usage(void);
void print_usage(void)
{
printf("Usage: test dirname\n");
}
int main(int argc,char *argv[])
{
DIR * dp;
struct dirent *filename;
if (argc < 2)
{
print_usage();
exit(1);
}
dp = opendir(argv[1]);
if (!dp)
{
fprintf(stderr,"open directory error\n");
return 0;
}
while (filename = readdir(dp))
{
printf("filename:%-10s\td_info:%ld\t d_reclen:%us\n",
filename->d_name,filename->d_ino,filename->d_reclen);
}
closedir(dp);
return 0;
}
參考
http://blog.csdn.net/zhuyi2654715/article/details/7605051
http://www.cnblogs.com/onlycxue/p/3154341.html