用C语言实现统计一个文件夹中各种文件的比例
2014-12-11 09:57
579 查看
原文:用C语言实现统计一个文件夹中各种文件的比例 《UNIX环境高级编程》中的程序清单4-7就介绍了如何实现递归地统计某个目录下面的文件!我刚开始看过它的代码后,觉得照着敲太没意思了,所以就合上书自己写了一遍!为此还写了一篇博文,这是博文地址: 在linux下用C语言实现递归查看某个目录中的所有文件【CSDN】!
今天做《Unix环境高级编程》的课后题,看到题目4.11这里提供了一种新的实现这个程序的思路,那就是每回读到一个目录,就通过chdir函数进入到这个目录,然后再通过opendir函数和readdir函数来读取这个目录中的文件,然后一个一个分析,如果是目录,则进行递归调用。如果不是目录,则对这个文件进行计数后立刻返回!这样一个一个分析完目录中的所有文件之后再来进行一个chdir(".."),返回到上一级的目录。具体的实现代码如下:
我这个代码并不是我自己合上书写的,而是在W.Richard Stevens书中给出的代码的基础上改的!在此要特别感谢这些真正的大神给我们提供了这么优秀的书籍!这是这个程序的运行结果,
那个第一行是我特意设置的,那个root是一个文件夹的名字,是属于root用户的,所以我这里并不能读取,会报出一个错误!下面是这个改进后的程序和原来书中的程序的一个对比,发现效率还真的是提高不少啊!
那个descend_hierarchy_p的那个程序是书上给的程序,每回读取都是读取的绝对路径的名称!而那个descend_hierarchy_ch命令就是每回碰到一个目录就进入到那个文件夹中,然后再来读取,这样每回读取的时候读取的就是相对路径的名称了!
今天做《Unix环境高级编程》的课后题,看到题目4.11这里提供了一种新的实现这个程序的思路,那就是每回读到一个目录,就通过chdir函数进入到这个目录,然后再通过opendir函数和readdir函数来读取这个目录中的文件,然后一个一个分析,如果是目录,则进行递归调用。如果不是目录,则对这个文件进行计数后立刻返回!这样一个一个分析完目录中的所有文件之后再来进行一个chdir(".."),返回到上一级的目录。具体的实现代码如下:
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<errno.h> #include<linux/limits.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<dirent.h> //所有函数的声明 typedef int MyFunc(const char *,const struct stat*,int); static MyFunc myfunc; //定义处理文件的函数 static int myftw(const char *,MyFunc *); static int dopath(MyFunc *); //定义的全局变量 static char *fullpath; //存放文件的名称的变量 static long sock_c,lnk_c,reg_c,blk_c,dir_c,chr_c,fifo_c,total_c; //统计各种文件类型的数量 //myfunc函数中需要定义的宏 #define FTW_F 1 //文件类型是文件 #define FTW_D 2 //文件类型是目录 #define FTW_NS 3 //一个文件不能stat #define FTW_ND 4 //一个目录不能被读 int main(int argc,char *argv[]) { if(argc != 2) { printf("Usage:%s pathname\n",argv[0]+2); exit(EXIT_FAILURE); } myftw(argv[1],myfunc); total_c = sock_c+lnk_c+reg_c+blk_c+dir_c+chr_c+fifo_c; if(0 == total_c) { total_c = 1; } printf("socket files = %7ld, %5.2f%%\n",sock_c,sock_c*100.0/total_c); printf("link files = %7ld, %5.2f%%\n",lnk_c,lnk_c*100.0/total_c); printf("regular files = %7ld, %5.2f%%\n",reg_c,reg_c*100.0/total_c); printf("block files = %7ld, %5.2f%%\n",blk_c,blk_c*100.0/total_c); printf("directory files = %7ld, %5.2f%%\n",dir_c,dir_c*100.0/total_c); printf("character files = %7ld, %5.2f%%\n",chr_c,chr_c*100.0/total_c); printf("FIFO files = %7ld, %5.2f%%\n",fifo_c,fifo_c*100.0/total_c); printf("total files = %7ld, %5.2f%%\n",total_c,total_c*100.0/total_c); return 0; } static int myftw(const char* pathname,MyFunc *pmyfunc) { int ret; fullpath = (char *)malloc(sizeof(char)*PATH_MAX); strcpy(fullpath,pathname); ret = dopath(myfunc); free(fullpath); return ret; } static int dopath(MyFunc *pmyfunc) { int ret; struct stat statbuf; char *ptr; DIR *dp; struct dirent* dirp; if(-1 == lstat(fullpath,&statbuf)) { ret = pmyfunc(fullpath,&statbuf,FTW_NS); return ret; } if(S_ISDIR(statbuf.st_mode) != 1) { ret = pmyfunc(fullpath,&statbuf,FTW_F); return ret; } //使目录文件++ if(0 != (ret=pmyfunc(fullpath,&statbuf,FTW_D))) return ret; //如果是目录文件则进入这个目录 if(-1 == chdir(fullpath)) { printf("%s[chdir]%s\n",fullpath,strerror(errno)); ret == -1; return ret; } //打开当前目录 if(NULL == (dp=opendir("."))) { ret = pmyfunc(fullpath,&statbuf,FTW_ND); return ret; } while(NULL != (dirp=readdir(dp))) { //忽略.和..文件(dot) if(0==strcmp(dirp->d_name,".") || 0==strcmp(dirp->d_name,"..")) continue; memset(fullpath,0,PATH_MAX); strcpy(fullpath,dirp->d_name); if(0 != (ret=dopath(myfunc))) //进行递归 break; } chdir(".."); //将当前目录设置为上一级目录 //对关闭文件进行判断 if(-1 == closedir(dp)) { printf("不能关闭%s\nError:%s",fullpath,strerror(errno)); } 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_IFSOCK: sock_c++; break; case S_IFLNK: lnk_c++; break; case S_IFREG: reg_c++; break; case S_IFBLK: blk_c++; break; case S_IFCHR: chr_c++; break; case S_IFIFO: fifo_c++; break; case S_IFDIR: printf("Error:这里不应该出现目录文件%s!\n\nError:%s\n",pathname,strerror(errno)); break; } break; case FTW_D: dir_c++; break; case FTW_ND: printf("不能打开目录%s\nError:%s\n",pathname,strerror(errno)); break; case FTW_NS: printf("不能打开文件%s\nError:%s\n",pathname,strerror(errno)); break; } return 0; }
我这个代码并不是我自己合上书写的,而是在W.Richard Stevens书中给出的代码的基础上改的!在此要特别感谢这些真正的大神给我们提供了这么优秀的书籍!这是这个程序的运行结果,
那个第一行是我特意设置的,那个root是一个文件夹的名字,是属于root用户的,所以我这里并不能读取,会报出一个错误!下面是这个改进后的程序和原来书中的程序的一个对比,发现效率还真的是提高不少啊!
那个descend_hierarchy_p的那个程序是书上给的程序,每回读取都是读取的绝对路径的名称!而那个descend_hierarchy_ch命令就是每回碰到一个目录就进入到那个文件夹中,然后再来读取,这样每回读取的时候读取的就是相对路径的名称了!
相关文章推荐
- 用C语言实现统计一个文件夹中各种文件的比例
- C语言实现的计算一个文件下的所有文件的总大小(还有BUG,如果文件夹下面还有文件家就有问题,等待更新)
- C语言 实现遍历一个文件夹的所有文件
- C语言实现打开一个文件(有内容的),统计这个文件中字符e出现了多少次
- 用c#实现 统计一个文件夹中的文件的个数 并用 FOR循环 依次读取文件的文件名
- 比较各种装箱试探方法实现文件C语言
- K个有序链表共N个结点在O(NlgK)时间合并为一个新的有序链表实现文件C语言
- Linux下c语言实现将一个目录下的所有文件和目录复制到另一个目录下
- 用mfc如何实现将一个文件拷贝到另一个文件夹中例如:C:\WINDOWS\a.txt中的a.txt文件拷贝到D:\Program
- shell 脚本实现统计文件夹下目录及文件个数
- VS 2008 VC 实现 --- 遍历一个文件夹下的所有文件(即查看文件名,不包含子目录)
- 用java实现将许多文件夹下的所有.avi文件拷贝到一个文件夹
- 本文以python实现了一个日志文件中ip提取与统计程序
- 编写一个类,该类具有统计文件长度,实现文件复制的函数。 其中复制功能函数如: void copy(string srcFileName,string targetFileName);
- 实现列举一个文件夹里的所有shp文件
- C语言实现递归删除文件夹及文件
- 统计一个指定文件夹下的文件数目。
- 复制一个文件夹中的所有文件和文件夹的java程序实现
- 编写一个类,该类具有统计文件长度,实现文件复制的函数。 其中复制功能函数如: void copy(string srcFileName,string targetFileName);
- [PHP][Function]实现将一个文件夹下的所有文件及文件夹复制到另一个文件夹里(保持原有结构