《UNIX环境高级编程》中的程序清单4-7就介绍了如何实现递归地统计某个目录下面的文件!我刚开始看过它的代码后,觉得照着敲太没意思了,所以就合上书自己写了一遍!为此还写了一篇博文,这是博文地址:在linux下用C语言实现递归查看某个目录中的所有文件【CSDN】!

  今天做《Unix环境高级编程》的课后题,看到题目4.11这里提供了一种新的实现这个程序的思路,那就是每回读到一个目录,就通过chdir函数进入到这个目录,然后再通过opendir函数和readdir函数来读取这个目录中的文件,然后一个一个分析,如果是目录,则进行递归调用。如果不是目录,则对这个文件进行计数后立刻返回!这样一个一个分析完目录中的所有文件之后再来进行一个chdir(".."),返回到上一级的目录。具体的实现代码如下:

  

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. #include<errno.h>
  5. #include<linux/limits.h>
  6. #include<unistd.h>
  7. #include<sys/types.h>
  8. #include<sys/stat.h>
  9. #include<dirent.h>
  10.  
  11. //所有函数的声明
  12. typedef int MyFunc(const char *,const struct stat*,int);
  13. static MyFunc myfunc; //定义处理文件的函数
  14. static int myftw(const char *,MyFunc *);
  15. static int dopath(MyFunc *);
  16.  
  17. //定义的全局变量
  18. static char *fullpath; //存放文件的名称的变量
  19. static long sock_c,lnk_c,reg_c,blk_c,dir_c,chr_c,fifo_c,total_c; //统计各种文件类型的数量
  20.  
  21. //myfunc函数中需要定义的宏
  22. #define FTW_F 1 //文件类型是文件
  23. #define FTW_D 2 //文件类型是目录
  24. #define FTW_NS 3 //一个文件不能stat
  25. #define FTW_ND 4 //一个目录不能被读
  26. int main(int argc,char *argv[])
  27. {
  28. if(argc != )
  29. {
  30. printf("Usage:%s pathname\n",argv[]+);
  31. exit(EXIT_FAILURE);
  32. }
  33. myftw(argv[],myfunc);
  34. total_c = sock_c+lnk_c+reg_c+blk_c+dir_c+chr_c+fifo_c;
  35. if( == total_c)
  36. {
  37. total_c = ;
  38. }
  39. printf("socket files = %7ld, %5.2f%%\n",sock_c,sock_c*100.0/total_c);
  40. printf("link files = %7ld, %5.2f%%\n",lnk_c,lnk_c*100.0/total_c);
  41. printf("regular files = %7ld, %5.2f%%\n",reg_c,reg_c*100.0/total_c);
  42. printf("block files = %7ld, %5.2f%%\n",blk_c,blk_c*100.0/total_c);
  43. printf("directory files = %7ld, %5.2f%%\n",dir_c,dir_c*100.0/total_c);
  44. printf("character files = %7ld, %5.2f%%\n",chr_c,chr_c*100.0/total_c);
  45. printf("FIFO files = %7ld, %5.2f%%\n",fifo_c,fifo_c*100.0/total_c);
  46. printf("total files = %7ld, %5.2f%%\n",total_c,total_c*100.0/total_c);
  47.  
  48. return ;
  49. }
  50. static int myftw(const char* pathname,MyFunc *pmyfunc)
  51. {
  52. int ret;
  53.  
  54. fullpath = (char *)malloc(sizeof(char)*PATH_MAX);
  55. strcpy(fullpath,pathname);
  56. ret = dopath(myfunc);
  57. free(fullpath);
  58.  
  59. return ret;
  60. }
  61. static int dopath(MyFunc *pmyfunc)
  62. {
  63. int ret;
  64. struct stat statbuf;
  65. char *ptr;
  66. DIR *dp;
  67. struct dirent* dirp;
  68.  
  69. if(- == lstat(fullpath,&statbuf))
  70. {
  71. ret = pmyfunc(fullpath,&statbuf,FTW_NS);
  72. return ret;
  73. }
  74. if(S_ISDIR(statbuf.st_mode) != )
  75. {
  76. ret = pmyfunc(fullpath,&statbuf,FTW_F);
  77. return ret;
  78. }
  79.  
  80. //使目录文件++
  81. if( != (ret=pmyfunc(fullpath,&statbuf,FTW_D)))
  82. return ret;
  83.  
  84. //如果是目录文件则进入这个目录
  85. if(- == chdir(fullpath))
  86. {
  87. printf("%s[chdir]%s\n",fullpath,strerror(errno));
  88. ret == -;
  89. return ret;
  90. }
  91.  
  92. //打开当前目录
  93. if(NULL == (dp=opendir(".")))
  94. {
  95. ret = pmyfunc(fullpath,&statbuf,FTW_ND);
  96. return ret;
  97. }
  98. while(NULL != (dirp=readdir(dp)))
  99. {
  100. //忽略.和..文件(dot)
  101. if(==strcmp(dirp->d_name,".") || ==strcmp(dirp->d_name,".."))
  102. continue;
  103. memset(fullpath,,PATH_MAX);
  104. strcpy(fullpath,dirp->d_name);
  105.  
  106. if( != (ret=dopath(myfunc))) //进行递归
  107. break;
  108. }
  109. chdir(".."); //将当前目录设置为上一级目录
  110. //对关闭文件进行判断
  111. if(- == closedir(dp))
  112. {
  113. printf("不能关闭%s\nError:%s",fullpath,strerror(errno));
  114. }
  115.  
  116. return ret;
  117. }
  118. static int myfunc(const char * pathname,const struct stat * statptr,int type)
  119. {
  120. switch(type)
  121. {
  122. case FTW_F:
  123. switch(statptr->st_mode & S_IFMT)
  124. {
  125. case S_IFSOCK: sock_c++; break;
  126. case S_IFLNK: lnk_c++; break;
  127. case S_IFREG: reg_c++; break;
  128. case S_IFBLK: blk_c++; break;
  129. case S_IFCHR: chr_c++; break;
  130. case S_IFIFO: fifo_c++; break;
  131. case S_IFDIR:
  132. printf("Error:这里不应该出现目录文件%s!\n\nError:%s\n",pathname,strerror(errno));
  133. break;
  134. }
  135. break;
  136. case FTW_D:
  137. dir_c++; break;
  138. case FTW_ND:
  139. printf("不能打开目录%s\nError:%s\n",pathname,strerror(errno));
  140. break;
  141. case FTW_NS:
  142. printf("不能打开文件%s\nError:%s\n",pathname,strerror(errno));
  143. break;
  144. }
  145. return ;
  146. }

  我这个代码并不是我自己合上书写的,而是在W.Richard Stevens书中给出的代码的基础上改的!在此要特别感谢这些真正的大神给我们提供了这么优秀的书籍!这是这个程序的运行结果,

  那个第一行是我特意设置的,那个root是一个文件夹的名字,是属于root用户的,所以我这里并不能读取,会报出一个错误!下面是这个改进后的程序和原来书中的程序的一个对比,发现效率还真的是提高不少啊!

  那个descend_hierarchy_p的那个程序是书上给的程序,每回读取都是读取的绝对路径的名称!而那个descend_hierarchy_ch命令就是每回碰到一个目录就进入到那个文件夹中,然后再来读取,这样每回读取的时候读取的就是相对路径的名称了!

用C语言实现统计一个文件夹中各种文件的比例的更多相关文章

  1. java基础 File 递归删除文件夹中所有文件文件夹 目录(包含子目录)下的.java文件复制到e:/abc文件夹中, 并统计java文件的个数

    File 递归删除文件夹中所有文件文件夹 package com.swift.kuozhan; import java.io.File; import java.util.Scanner; /*键盘录 ...

  2. 【转载】C#代码开发过程中如何快速比较两个文件夹中的文件的异同

    在日常的使用电脑的过程中,有时候我们需要比较两个文件夹,查找出两个文件夹中不同的文件以及文件中不同的内容信息,进行内容的校对以及合并等操作.其实使用Beyond Compare软件即可轻松比较,Bey ...

  3. 基于Python——实现两个文件夹中的文件拷贝

    [背景]当复制一个文件夹中的某文件到另一个文件夹中时是一件很容易的事情,可是如果存在很多文件夹中的文件需要一一拷贝,就会变的很繁琐,稍有不慎就会遗漏,今天就用Python来解决这个问题—— [代码实现 ...

  4. C++获取文件夹中所有文件

    获取文件夹中的文件,用到过很多次,每次用的时候都要去查下,很烦,所以想自己写下,当然,借鉴了很多其他大佬的博客 主要实现的函数,如下: void getFiles( string path, vect ...

  5. python 遍历文件夹中所有文件

    '''使用walk方法递归遍历目录文件,walk方法会返回一个三元组,分别是root.dirs和files. 其中root是当前正在遍历的目录路径:dirs是一个列表,包含当前正在遍历的目录下所有的子 ...

  6. cocos项目导入其它源文件时加入依赖库时,头文件提示找不到文件夹中的文件

    cocos项目导入其它源文件时加入依赖库时,头文件提示找不到文件夹中的文件解决方法: 选择项目属性->c/c++->常规,在附加包括项目中加上对应的文件夹 cocos test项目的库(所 ...

  7. python遍历文件夹中所有文件夹和文件,os.walk

    python中可以用os.walk来遍历某个文件夹中所有文件夹和文件. 例1: import os filePath = 'C:/Users/admin/Desktop/img' for dirpat ...

  8. Python列出文件夹中的文件

    几乎所有的关于操作系统的内容可以在python 官方文档中找到:https://docs.python.org/3/library/os.html#module-os 其中os.path被单独列出:h ...

  9. python将test01文件夹中的文件剪切到test02文件夹中

    将test01文件夹中的文件剪切到test02文件夹中 import shutil import os def remove_file(old_path, new_path): print(old_p ...

随机推荐

  1. [AngularJS] Provider

    This lesson describes what is really happening when you use the angularfactory and how you can make ...

  2. codeigniter分页类传多个参数(转)

    http://example.com/index.php/控制器/方法名/页面的偏移值 页面的偏移值必须是方法名后第一个参数,否者分页类不能判断当前是哪一页,而用ci的分页类进行页面跳转时他是把偏移值 ...

  3. C#_ajax fileupload

    @{ ViewBag.Title = "Index"; Layout = null; } <h2>Index</h2> <script src=&qu ...

  4. Intellij IDEA 使用Debug模式运行非常慢

    今天在用Debug的时候,idea运行非常慢,搜了一下有人说: 自己检查发现果然如此,把在方法前的断点去掉(移到方法体内),就正常了.

  5. jq宽高 详解

    alert($(window).height()); //浏览器时下窗口可视区域高度 alert($(document).height()); //浏览器时下窗口文档的高度 alert($(docum ...

  6. iOS之与JS交互通信

    随着苹果SDK的不断升级,越来越多的新特性增加了进来,本文主要讲述从iOS6至今,Native与JavaScript的交互方法 一.UIWebview && iframe && ...

  7. Objective-C基础笔记一

    这里开始了我OC旅程 花了8天的时间粗略的学习了新知识Objective-C(简称OC),虽然只是学习了其中的基础部分,但经过这一周的学习也算是入门了.对面向对象的封装.继承.多态以及其中所包含的方法 ...

  8. Objective-C ,ios,iphone开发基础:3分钟教你做一个iphone手机浏览器

    第一步:新建一个Single View工程: 第二步:新建好工程,关闭arc. 第三步:拖放一个Text Field 一个UIButton 和一个 UIWebView . Text Field 的ti ...

  9. webservice简单总结

    一:webservice定义 webservice是一种基于xml,xsd封装格式,通过http协议通信的一种服务,支持跨平台.跨语言的 远程调用. 二:webservice优点 1:跨平台,无论是w ...

  10. LeetCode 75

    Sort Colors Given an array with n objects colored red, white or blue, sort them so that objects of t ...