一、目錄掃描函數及其相關結構
1. struct dirent *readdir(DIR *dp);
2. DIR *opendir(const char *name);
4. int closedir(DIR *dp);
5. void rewinddir(DIR *dp);
6. void seekdir(DIR *dp,long loc);
7. long telldir(DIR *dp);
8. int mkdir(const char *pathname, mode_t mode);
9. int rmdir(const char *pathname);
10. int chmod(const char *path, mode_t mode);//改變文件或目錄的屬性
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;
struct dirent
{
long d_ino; /* inode number索引節點號 */
off_t d_off; /* offset to this dirent在目錄文件中的偏移 */
unsigned short d_reclen; /* length of this d_name文件名長 */
unsigned char d_type; /* the type of d_name文件類型 */
char d_name [NAME_MAX+1]; /* file name (null-terminated)文件名,最長255字符 */
}
從上述定義也能夠看出來,dirent結構體存儲的關於文件的信息很少,所以dirent同樣也是起着一個索引的作用,如果想獲得類似ls -l那種效果的文件信息,必須要靠stat函數了。
通過readdir函數讀取到的文件名存儲在結構體dirent的d_name成員中,而函數
int stat(const char *file_name, struct stat *buf);
int fstat(int filedes, struct stat *buf);
int lstat(const char *path, 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目下/a/b)b文件的詳細信息,分爲以下3步(詳情見下面例子):
1.opendir函數打開目錄a,返回指向目錄a的DIR結構體c。
2.readdir( c)函數讀取目錄a下所有文件(包括目錄),返回指向目錄a下所有文件的dirent結構體d。
3.遍歷d,調用stat(d->name,stat *e)來獲取每個文件的詳細信息,存儲在stat結構體e中。
二、打印目錄下所有文件及目錄的程序
#include <unistd.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <stdlib.h>
//dir爲目錄名,depth爲空格個數
void printdir(char *dir, int depth)
{
DIR* dp;
struct dirent* entry;
struct stat statbuf;
if(NULL == (dp = opendir(dir))) //打開dir目錄
{
fprintf(stderr, "Can`t open directory %s\n", dir);
return ;
}
chdir(dir);//cd dir
while(NULL != (entry = readdir(dp)))
{
lstat(entry->d_name, &statbuf); //獲取文件名信息
if (S_ISDIR(statbuf.st_mode)) { //如果爲目錄
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)//如果爲當前或上一目錄,則讀取下一個文件
continue;
printf("%*s%s/\n", depth, "", entry->d_name);
printdir(entry->d_name,depth+4); //爲空格個數
} else
printf("%*s%s\n", depth, "", entry->d_name);
}
chdir(".."); //返回上一路徑
closedir(dp); //關閉目錄
}
int main(void)
{
char topdir[32] = {0};
printf("plese input scan of Directory: ");
scanf("%s", topdir);
printf("Directory scan of %s\n", topdir);
printdir(topdir, 0);
printf("done.\n");
return 0;
}
a目錄下的目錄及文件爲:
[root@localhost a]# ls
1.c 2.c 3.txt b
[root@localhost b]# ls
a.c b.c c c.c
[root@localhost c]# ls
e.c f.c
掃描a目錄,結果爲:
[root@localhost for_test]# ./a.out
plese input scan of Directory: ./a
111:./a 111Directory scan of ./a
b/
c.c
c/
e.c
f.c
b.c
a.c
3.txt
2.c
1.c
done.
能掃描目錄,當然就能對目錄下的文件或目錄進行操作了!