目录扫描程序详解

linux程序设计 第4版  第104页

#include<unistd.h>
#include<stdio.h>
#include<dirent.h>
#include<string.h>
#include<sys/stat.h>
#include<stdlib.h>

void printdir(char *dir, int depth)
{
        DIR *dp;
        struct dirent *entry;
        struct stat statbuf;

        if ((dp = opendir(dir)) == NULL)
        {
                fprintf(stderr, "cannot open directory: %s\n", dir);
                return;
        }
        chdir(dir);
        while ((entry = readdir(dp)) != NULL)
        {
                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()
{
        printf("Directory scan of /home:\n");
        printdir("/home", 0);
        printf("done. \n");

        exit(0);
}


这个程序扫描 /home目录并输出。

初看也是一头雾水,于是进行具体函数分析:

14:原型:DIR *opendir(const char *name) : 打开一个目录并建立一个目录流,如果成功,它返回一个指向DIR结构的指针,该指针用于读取目录数据项,失败时返回一个

        空指 针。此处返回的指针为dp ,dp在第10 行已经被定义为 DIR结构,此结构在头文件 dirent.h 头文件中,作为目录操作的基础。此行语句判断若打开目录失败的情况

16: 原型:int fprintf(FILE *stream, const char *format, ...) :把自己的输出送到一个指定的文件流。

          此处为:若上面的 目录打开失败,则返回  cannot open directory 到标准错误stderr中

19: 原型:int chdir(const char *path):像shell中cd命令切换目录一样。此处为 若打开目录成功,则进入该目录

20: 原型:struct dirent *readdir(DIR *dirp):返回一个指针,该指针指向的结构里保存着目录流dirp中下一个目录项的有关资料,后续的 readdir 调用将返回后续的目录项,

         发生错误返回NULL。此处entry已在第11行定义为对应类型,

22:原型:int lstat(const char *path, struct stat *buf):通过文件名查找对应状态信息,statbuf已在第12行定义为相应类型,entry为dirent结构,该结构中包含

        ino_t  d_ino: 文件的inode节点号,char d_name[ ] : 文件的名字,mode_t st_mode: 文件权限与类型信息 ,等。此处通过文件名查找信息

23:S_ISDIR为宏定义,测试statbuf.st_mode是否是目录

25~27:跳过 d_name 为  .  和  ..  的数据项

28:printf("%*s%s/\n", depth, "", entry->d_name);  % *s  代表输出depth长度的""(空格)。输出目录名,并在每个目录后加上 /

29:printdir 函数调用自己并再次进入下一层目录处理,并缩进4个字节 。

31:如果不是目录,则名字后面不加 /

33:返回上级目录,从而可继续上级目录的遍历(通过29行调用)

34:原型:int closedir(DIR *dirp):关闭一个目录流并释放与之关联的资源   

39:主函数调用printfdir ,扫描/home目录,初始缩进为0

40:程序结束时 输出:done.  

 程序虽小,包含的函数还真不少,开始对函数不熟悉,现在都放一起分析下,整个程序畅通多了。     



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值