免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1038 | 回复: 1
打印 上一主题 下一主题

[C] 文件遍历 [复制链接]

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-08-12 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-07-10 09:38 |只看该作者 |倒序浏览
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <sys/termios.h>
  4. #include <sys/ioctl.h>
  5. #include <stdio.h>  
  6. #include <stdlib.h>  
  7. #include <stddef.h>  
  8. #include <string.h>  
  9. #include <unistd.h>  
  10. #include <signal.h>  
  11. #include <errno.h>     
  12. #include <stdarg.h>   
  13. #include <limits.h>
  14. #include <fcntl.h>
  15. #include <dirent.h>
  16. #ifdef   PATH_MAX
  17. static int   pathmax = PATH_MAX;
  18. #else
  19. static int   pathmax = 0;
  20. #endif
  21. #define SUSV3 200112L
  22. static long posix_version = 0;
  23. #define PATH_MAX_GUESS   1024
  24. char *path_alloc(int *sizep) /* also return allocated size, if nonnull */
  25. {
  26.         char *ptr;
  27.         int size;
  28.         if (posix_version == 0)
  29.                        posix_version = sysconf(_SC_VERSION);
  30.         if (pathmax == 0)
  31.         {     /* first time through */
  32.                        errno = 0;
  33.                        if ((pathmax = pathconf("/", _PC_PATH_MAX)) < 0)
  34.                 {
  35.                          if (errno == 0)
  36.                                     pathmax = PATH_MAX_GUESS; /* it's indeterminate */
  37.                          else
  38.                                     return printf("pathconf error for _PC_PATH_MAX");
  39.                        }
  40.                 else
  41.                          pathmax++;    /* add one since it's relative to root */
  42.         }
  43.         if (posix_version < SUSV3)
  44.                        size = pathmax + 1;
  45.         else
  46.                        size = pathmax;
  47.         if ((ptr = malloc(size)) == NULL)
  48.                        return printf("malloc error for pathname");
  49.         if (sizep != NULL)
  50.                        *sizep = size;
  51.         return(ptr);
  52. }
  53. typedef int Myfunc(const char *,const struct stat *,int);
  54. static Myfunc myfunc;
  55. static int myftw(char *,Myfunc *);
  56. static int dopath(Myfunc *);
  57. static long nreg,ndir,nblk,nchr,nfifo,nslink,nsock,ntot;
  58. int main(int argc,char *argv[])
  59. {
  60.         int ret;
  61.         if(argc != 2)
  62.                 return printf("usage: ftw <statring-pathname>");
  63.         ret=myftw(argv[1],myfunc);
  64.         ntot=nreg+ndir+nblk+nchr+nfifo+nslink+nsock;
  65.         if(ntot==0)
  66.                 ntot=1;
  67.         printf("regular files =%7ld, %5.2f %%\n",nreg,nreg*100.0/ntot);
  68.         printf("directories   =%7ld, %5.2f %%\n",ndir,ndir*100.0/ntot);
  69.         printf("block special =%7ld, %5.2f %%\n",nblk,nblk*100.0/ntot);
  70.         printf("char special  =%7ld, %5.2f %%\n",nchr,nchr*100.0/ntot);
  71.         printf("FIFOs         =%7ld, %5.2f %%\n",nfifo,nfifo*100.0/ntot);
  72.         printf("symbolic links=%7ld, %5.2f %%\n",nslink,nslink*100.0/ntot);
  73.         printf("sockets       =%7ld, %5.2f %%\n",nsock,nsock*100.0/ntot);
  74.         exit(ret);
  75. }
  76. #define FTW_F 1        /* file other than directory */
  77. #define FTW_D 2        /* directory */
  78. #define FTW_DNR 3 /* directory that can't be read */
  79. #define FTW_NS 4 /* file that we can't stat */
  80. static char *fullpath;
  81. static size_t pathlen;
  82. static int myftw(char *pathname,Myfunc *func)
  83. {
  84.         fullpath=path_alloc(&pathlen);
  85.         if(pathlen<=strlen(pathname))
  86.         {
  87.                 pathlen=strlen(pathname)*2;
  88.                 if((fullpath=realloc(fullpath,pathlen))==NULL)
  89.                         return printf("realloc failed");
  90.         }
  91.         strcpy(fullpath,pathname);
  92.         return (dopath(func));
  93. }
  94. static int dopath(Myfunc *func)
  95. {
  96.         struct stat statbuf;
  97.         struct dirent *dirp;
  98.         DIR *dp;
  99.         int ret,n;
  100.         if(lstat(fullpath,&statbuf)<0)
  101.                 return (func(fullpath,&statbuf,FTW_NS));
  102.         if(S_ISDIR(statbuf.st_mode)==0)
  103.                 return(func(fullpath,&statbuf,FTW_F));
  104.         if((ret=func(fullpath,&statbuf,FTW_D))!=0)
  105.                 return (ret);
  106.         n=strlen(fullpath);
  107.         if(n+NAME_MAX+2>pathlen)
  108.         {
  109.                 pathlen*=2;
  110.                 if((fullpath=realloc(fullpath,pathlen))==NULL)
  111.                         return printf("realloc failed");
  112.         }
  113.         fullpath[n++]='/';
  114.         fullpath[n]=0;
  115.         if((dp=opendir(fullpath))==NULL)
  116.                 return (func(fullpath,&statbuf,FTW_DNR));
  117.         while((dirp=readdir(dp))!=NULL)
  118.         {
  119.                 if(strcmp(dirp->d_name,".")==0 || strcmp(dirp->d_name,"..")==0);
  120.                         continue;
  121.                 strcpy(&fullpath[n],dirp->d_name);
  122.                 if((ret=dopath(func))!=0)
  123.                         break;
  124.         }
  125.         fullpath[n-1]=0;
  126.         if(closedir(dp)<0)
  127.                 printf("can't close director %s",fullpath);
  128.         return ret;
  129. }
  130. static int myfunc(const char *pathname,const struct stat *statptr,int type)
  131. {
  132.         switch(type)
  133.         {
  134.         case FTW_F:
  135.                 switch(statptr->st_mode & S_IFMT)
  136.                 {
  137.                         case S_IFREG:
  138.                                 nreg++;
  139.                                 break;
  140.                         case S_IFBLK:
  141.                                 nblk++;
  142.                                 break;
  143.                         case S_IFCHR:
  144.                                 nchr++;
  145.                                 break;
  146.                         case S_IFIFO:
  147.                                 nfifo++;
  148.                                 break;
  149.                         case S_IFLNK:
  150.                                 nslink++;
  151.                                 break;
  152.                         case S_IFSOCK:
  153.                                 nsock++;
  154.                                 break;
  155.                 }
  156.         case FTW_D:
  157.                 ndir++;
  158.                 break;
  159.         case FTW_DNR:
  160.                 printf("can't read directory %s",pathname);
  161.                 break;
  162.         default:
  163.                 break;
  164.         }
  165.         return 0;
  166. }
复制代码

论坛徽章:
12
2015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之同曦
日期:2017-03-17 19:13:162016科比退役纪念章
日期:2016-11-07 08:28:12luobin
日期:2016-06-17 17:46:36wusuopu
日期:2016-06-17 17:43:4515-16赛季CBA联赛之福建
日期:2016-01-14 12:49:22程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2015-06-08 22:20:00程序设计版块每日发帖之星
日期:2015-06-08 22:20:002015年亚洲杯之科威特
日期:2015-03-24 14:21:272015年迎新春徽章
日期:2015-03-04 09:57:092016科比退役纪念章
日期:2018-04-10 16:20:18
2 [报告]
发表于 2015-07-10 10:05 |只看该作者
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/termios.h>
#include <sys/ioctl.h>
#include <stdio.h>  
#include <stdlib.h>  
#include <stddef.h>  
#include <string.h>  
#include <unistd.h>  
#include <signal.h>  
#include <errno.h>     
#include <stdarg.h>   
#include <limits.h>
#include <fcntl.h>
#include <dirent.h>
#ifdef   PATH_MAX
static int   pathmax = PATH_MAX;
#else
static int   pathmax = 0;
#endif
#define SUSV3 200112L
static long posix_version = 0;
#define PATH_MAX_GUESS   1024
char *path_alloc(int *sizep) /* also return allocated size, if nonnull */
{
        char *ptr;
        int size;
        if (posix_version == 0)
                       posix_version = sysconf(_SC_VERSION);
        if (pathmax == 0)
        {     /* first time through */
                       errno = 0;
                       if ((pathmax = pathconf("/", _PC_PATH_MAX)) < 0)
                {
                         if (errno == 0)
                                    pathmax = PATH_MAX_GUESS; /* it's indeterminate */
                         else
                                    return printf("pathconf error for _PC_PATH_MAX");
                       }
                else
                         pathmax++;    /* add one since it's relative to root */
        }
        if (posix_version < SUSV3)
                       size = pathmax + 1;
        else
                       size = pathmax;
        if ((ptr = malloc(size)) == NULL)
                       return printf("malloc error for pathname");
        if (sizep != NULL)
                       *sizep = size;
        return(ptr);
}
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)
                return printf("usage: ftw <statring-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("directories   =%7ld, %5.2f %%\n",ndir,ndir*100.0/ntot);
        printf("block special =%7ld, %5.2f %%\n",nblk,nblk*100.0/ntot);
        printf("char special  =%7ld, %5.2f %%\n",nchr,nchr*100.0/ntot);
        printf("FIFOs         =%7ld, %5.2f %%\n",nfifo,nfifo*100.0/ntot);
        printf("symbolic links=%7ld, %5.2f %%\n",nslink,nslink*100.0/ntot);
        printf("sockets       =%7ld, %5.2f %%\n",nsock,nsock*100.0/ntot);
        exit(ret);
}
#define FTW_F 1        /* file other than directory */
#define FTW_D 2        /* directory */
#define FTW_DNR 3 /* directory that can't be read */
#define FTW_NS 4 /* file that we can't stat */
static char *fullpath;
static size_t pathlen;
static int myftw(char *pathname,Myfunc *func)
{
        fullpath=path_alloc(&pathlen);
        if(pathlen<=strlen(pathname))
        {
                pathlen=strlen(pathname)*2;
                if((fullpath=realloc(fullpath,pathlen))==NULL)
                        return printf("realloc failed");
        }
        strcpy(fullpath,pathname);
        return (dopath(func));
}
static int dopath(Myfunc *func)
{
        struct stat statbuf;
        struct dirent *dirp;
        DIR *dp;
        int ret,n;
        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);
        n=strlen(fullpath);
        if(n+NAME_MAX+2>pathlen)
        {
                pathlen*=2;
                if((fullpath=realloc(fullpath,pathlen))==NULL)
                        return printf("realloc failed");
        }
        fullpath[n++]='/';
        fullpath[n]=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(&fullpath[n],dirp->d_name);
                if((ret=dopath(func))!=0)
                        break;
        }
        fullpath[n-1]=0;
        if(closedir(dp)<0)
                printf("can't close director %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 FTW_D:
                ndir++;
                break;
        case FTW_DNR:
                printf("can't read directory %s",pathname);
                break;
        default:
                break;
        }
        return 0;
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP