unix环境高级编程-4.21-读目录

本节主要讲述了对unix系统对读目录的讲述。首先了解一下了解一下下面的函数

#include <dirent.h>

DIR* opendir(const char* pathname);
                    成功返回指针,错误返回null;

struct dirent *readdir(DIR *dp);//成功返回其指针,若在目录结尾或出错则返回null;

void rewinddir(DIR* dp);

int closedir(DIR* dp);//成功返回0,出错返回-1;

long telldir(DIR* dp);//返回与dp关联的目录中的当前的位置

void seekdir(DIR * dp,long loc);

 

struct dirent * readdir (DIR *dirstream) [Function]
This function reads the next entry from the directory. It normally returns a pointer to
a structure containing information about the file. This structure is statically allocated
and can be rewritten by a subsequent call.
Portability Note: On some systems readdir may not return entries for ‘.’ and ‘..’,
even though these are always valid file names in any directory. See Section 11.2.2
[File Name Resolution], page 224.
If there are no more entries in the directory or an error is detected, readdir returns
a null pointer. The following errno error conditions are defined for this function:
EBADF The dirstream argument is not valid.
readdir is not thread safe. Multiple threads using readdir on the same dirstream
may overwrite the return value. Use readdir_r when this is critical.

 

 

int closedir (DIR *dirstream) [Function]
This function closes the directory stream dirstream. It returns 0 on success and -1
on failure.
The following errno error conditions are defined for this function:
EBADF The dirstream argument is not valid.

其他的就不写了,本章主要是通过运用以上函数来实现遍历目录层次结构,并按文件类型进行技术。

 

直接上代码:

#include "apue.h"
#include <dirent.h>
#include<limits.h>

typedef int Myfunc(const char* ,const struct stat* ,int);

static Myfunc myfunc;

static int myftw(char* ,Myfunc*);

static int dopath(Myfunc *);

static long nreg,ndir,nblk,nchr,nfifo,nslink,nsock,ntot;

int main(int argc,char** argv)
{
    int ret;
    if(argc!=2)
        err_quit("usage:ftw<starting-pathname>");

    ret=myftw(argv[1],myfunc);

    ntot=nreg+ndir+nblk+nchr+nfifo+nslink+nsock;

    if(ntot==0)
        ntot=1;
    printf("regular files= %7ld,%5.2f %%\n",nreg,nreg*100.0/ntot);
    printf("regular files= %7ld,%5.2f %%\n",ndir,ndir*100.0/ntot);
    printf("regular files= %7ld,%5.2f %%\n",nblk,nblk*100.0/ntot);
    printf("regular files= %7ld,%5.2f %%\n",nchr,nchr*100.0/ntot);
    printf("regular files= %7ld,%5.2f %%\n",nfifo,nfifo*100.0/ntot);
    printf("regular files= %7ld,%5.2f %%\n",nslink,nslink*100.0/ntot);
    printf("regular files= %7ld,%5.2f %%\n",nsock,nsock*100.0/ntot);

}

char*path_alloc(int* size)
 {
 char *p = NULL;
 if(!size) return NULL;
 p = malloc(256);
 if(p)
 *size = 256;
 else
 *size = 0;
 return p;
 }



 #define FTW_F 1
 #define FTW_D 2
 #define FTW_DNR 3
 #define FTW_NS 4

 static char *fullpath;

 static int myftw(char* pathname,Myfunc* func)
 {
    int len;
    fullpath=path_alloc(&len);

    strncpy(fullpath,pathname,len);
    fullpath[len-1]=0;

    return (dopath(func));

 }


 static int dopath(Myfunc* func)
 {
    struct stat statbuf;
    struct dirent *dirp;
    DIR* dp;
    int ret;
    char *ptr;

    if(lstat(fullpath,&statbuf)<0)
        return (func(fullpath,&statbuf,FTW_NS));

    if(S_ISDIR(statbuf.st_mode)==0)
        return (func(fullpath ,&statbuf, FTW_F));
    

    if((ret=func(fullpath,&statbuf,FTW_D))!=0)
        return (ret);

     ptr=fullpath+strlen(fullpath);
     *ptr++='/';
     *ptr=0;

     if((dp=opendir(fullpath))==NULL)
        return(func(fullpath,&statbuf,FTW_DNR));


      while((dirp=readdir(dp))!=NULL){
          if(strcmp(dirp->d_name,".")==0||
             strcmp(dirp->d_name,"..")==0)
             continue;

         strcpy(ptr,dirp->d_name);

         if((ret=dopath(func))!=0)
            break;

          }
        ptr[-1]=0;
        if(closedir(dp)<0)
            err_ret("can't clost dir %s",fullpath);

        return(ret);

 }


 static int myfunc(const char* pathname,const struct stat* statptr,int type)
 {

    switch(type)
    {
        case FTW_F:
           switch(statptr->st_mode &S_IFMT){
            case S_IFREG:nreg++;break;
            case S_IFBLK:nblk++;break;
            case S_IFCHR:nchr++;break;
            case S_IFIFO:nfifo++;break;
            case S_IFLNK:nslink++;break;
            case S_IFSOCK:nsock++;break;
            case S_IFDIR:
                  err_dump("for S_IFDIR for %s",pathname);
            }
            break;
        case FTW_D:
             ndir++;
             break;

        case FTW_DNR:
             err_ret("can't read directory %s",pathname);
             break;

        case FTW_NS:
             err_ret("stat error for %s",pathname);
             break;

        default:
             err_dump("unkown type %d for pathname %s",type,pathname);

        }

        return(0);

 }


这个经过修正可以正常运行了

运行结果

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值