#include<dirent.h>
#include<limits.h>
#include<sys/stat.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h> #define FTW_F 1 //标记非目录文件
#define FTW_D 2 //标记目录文件
#define FTW_DNR 3 //标记不可读目录
#define FTW_NS 4 //标记不可获得stat的文件 static char *fullpath; //保存文件的全路径
static size_t pathlen; //保存文件的路径长度 //定义处理文件的函数
typedef int Myfunc(const char *,const struct stat*,int);
static Myfunc myfunc;
static int myftw(char *,Myfunc *);
static int dopath(Myfunc *);
char *path_alloc(size_t *size_t); /*
nreg:普通文件的个数; ndir: 目录文件的数量; nblk:块特殊文件的数量
nchr:字符特殊文件的数量 nfifo:管道特殊文件的数量
nslink:符号连接特殊文件的数量; nsock:套接字文件数量; ntot:总文件数量
*/
static long nreg,ndir,nblk,nchr,nfifo,nslink,nsock,ntot; int main( int argc, char *argv[])
{
int ret; if(argc != )
{
printf("falut command input !\n");
exit();
} //计算各类文件的个数
ret = myftw(argv[],myfunc); ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock; //避免除以0
if(ntot == )
{
ntot = ;
} printf("regular files = %7ld,%5.2f %%\n",nreg,nreg*100.0 / ntot);
printf("direciotn files = %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("sockers = %7ld,%5.2f %%\n",nsock,nsock*100.0 / ntot); } //处理pathname并保存在一个全局的字符数组中,调用dopath
static int myftw(char *pathname,Myfunc *func)
{
//为保存路径的字符串数组分配空间
fullpath = path_alloc(&pathlen); //如果分配内存空间不够就重新分配
if(pathlen <= strlen(pathname))
{
pathlen = strlen(pathname) * ;
if((fullpath = realloc(fullpath,pathlen )) == NULL);
printf("realloc failed\n");
}
//将路径名参数保存到全路径中,fullpath是全局变量,dopath函数可以调用
strcpy(fullpath,pathname); return (dopath(func));
} //路径数组分配
char *path_alloc(size_t *size)
{
char *p = NULL;
if(!size)
return NULL;
p = malloc();
if(p)
*size = ;
else
*size = ; return p;
} //dopath用于判断是否是目录,然后根据选择情况是直接进入myfun函数取技术
//还是递归调用dopath函数
static int dopath(Myfunc *func)
{
struct stat statbuf;
struct dirent *dirp;
DIR *dp;
int ret,n; //调用lstat获取路径名的stat信息,如果不成功,调用func函数,并传递给FTW_NS
if(lstat(fullpath,&statbuf) < )
return (func(fullpath, &statbuf, FTW_NS)); //查看文件stat结构的st_mode,如果不是目录,调用func函数
//并传递给FTW_F,交由myfun进一步判断文件类型
if(S_ISDIR(statbuf.st_mode) == )
return(func(fullpath,&statbuf,FTW_F)); //最后一种情况就是该路径名代表的是一个目录,此次的fun的正常情况返回0
//所以执行完func后还不会返回,会继续执行func
if((ret = func(fullpath,&statbuf,FTW_D)) != )
return(ret); //路径处理,扩充路径空间长度
n = strlen(fullpath);
if(n + NAME_MAX + > pathlen)
{
pathlen *= ;
if((fullpath = realloc(fullpath,pathlen)) == NULL)
{
printf("realoc failed\n");
}
} fullpath[n++] = '/';
fullpath[n] = ; //处理每个目录项
if((dp = opendir(fullpath)) == NULL)
return (func(fullpath,&statbuf,FTW_DNR));
while((dirp = readdir(dp)) != NULL)
{
//忽略当前目录(.)和上一级目录(..)以避免进入死循环
if(strcmp(dirp->d_name,".") == ||
strcmp(dirp->d_name,"..") == )
continue;
strcpy(&fullpath[n],dirp->d_name); //在“/”之后加上当前目录项的命中 if((ret = dopath(func)) != ) //然后采用新的路径名递递归的调用dopath
break;
} fullpath[n-] = ; //关闭目录
if(closedir(dp) < )
printf("can't close directory %s",fullpath); return ret; } //通过stat结构的st_mode字段来判断文件的类型,并计数
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:
printf("for S_IFDIR for %s",pathname);
}
break; //对于目录文件进行处理
case FTW_D:
ndir++;
break;
//对于不可读目录进行处理
case FTW_DNR:
printf("%s dir isn't read",pathname);
break;
case FTW_NS:
printf("%s stat error",pathname); default:
printf("%d type aren't identified, path is %s",type,pathname);
} return ;
}

C语言实现文件类型统计函数的更多相关文章

  1. delphi中的各种文件类型介绍【转】

    1.DPR: Delphi Project文件,包含了Pascal代码.应用系统的工程文件2.PAS: Pascal文件,Pascal单元的源代码,可以是与窗体有关的单元或是独立的单元.3.DFM:D ...

  2. BMP头文件格式以及C语言读取头文件【转】

    BMP头文件格式以及C语言读取头文件[转] (2011-12-24 22:59:17) 转载▼ 标签: 杂谈 分类: 各个领域的知识 BMP图像文件由三部分组成:位图文件头数据结构,它包含BMP图像文 ...

  3. Delphi 文件类型

    该内容整理自以下链接 http://www.cnblogs.com/chenyunpeng/archive/2012/08/02/2620513.html 1.DPR: Delphi Project文 ...

  4. 「C语言」文件的概念与简单数据流的读写函数

    写完「C语言」单链表/双向链表的建立/遍历/插入/删除 后,如何将内存中的链表信息及时的保存到文件中,又能够及时的从文件中读取出来进行处理,便需要用到”文件“的相关知识点进行文件的输入.输出. 其实, ...

  5. 编译流程,C开发常见文件类型名

    编译流程 我们常说的编译是一个整体的概念,是指从源程序到可执行程序的整个过程,实际上,C语言编译的过程可以进一步细分为预编译->编译->汇编->链接 预编译是把include关键字所 ...

  6. 诠释Linux中『一切都是文件』概念和相应的文件类型

    导读 在 Unix 和它衍生的比如 Linux 系统中,一切都可以看做文件.虽然它仅仅只是一个泛泛的概念,但这是事实.如果有不是文件的,那它一定是正运行的进程. 要理解这点,可以举个例子,您的根目录( ...

  7. linux 文件类型 文件权限

    linux中常见的文件类型有: “—”表示普通文件 :-rw-r--r-- 1 root root 41727 07-13 02:56 install.log   “d”表示目录 :drwxr-xr- ...

  8. Python的文件类型

    Python的文件类型主要分为3种:源代码(source file).字节码(byte-code file).优化的字节码(optimized file).这些代码都可以直接运行,不需要编译或者连接. ...

  9. C 语言 .h文件的作用

    C语言头文件的作用 最近在工作当中遇到了一点小问题,关于C语言头文件的应用问题,主要还是关于全局变量的定义和声明问题.学习C语言已经有好几年了,工作使用也近半年了,但是对于这部分的东西的确还没有深入的 ...

随机推荐

  1. JavaScript是单线程还是多线程(转)

    多线程要考虑线程之间的资源抢占,死锁,冲突之类一系列问题.JavaScript作为一门客户端脚本,貌似没有多线程的一些列问题.那么JavaScript是单线程还是多线程?通过查资料总结了JavaScr ...

  2. 监听EF执行的sql语句及状态

    1.监听EF执行sql的方式 db.Database.Log += c => Console.WriteLine($"sql:{c}"); SQL Server Profil ...

  3. C#学习笔记------参数

    一.形参 形参是本地变量,它声明在方法的参数列表中,而不是方法体中.

  4. C# vb .net实现gamma伽玛调整特效滤镜

    在.net中,如何简单快捷地实现Photoshop滤镜组中的gamma伽玛调整特效滤镜呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: ...

  5. Libev库学习

    Libev库学习 https://www.cnblogs.com/wunaozai/p/3950249.html Libev库学习(1)https://www.cnblogs.com/wunaozai ...

  6. 5_PHP数组_3_数组处理函数及其应用_7_数组排列函数

    以下为学习孔祥盛主编的<PHP编程基础与实例教程>(第二版)所做的笔记. 数组排列函数 1. sort() 函数 程序: <?php $array = array("img ...

  7. 关于Eclipse导入maven项目报空指针异常

    今天新建了一个maven项目,因为是通过公司的工具新建的,代码拉下来就有src.pom.xml文件. 导入Eclipse却报空指针异常.具体如下: An error has occurred. See ...

  8. 关于 JS this

    关于 JS this 1. this 与 普通函数 2. this 与 bind.call.apply 3. this 与 箭头函数 4. this 与 return 4.1 返回 引用对象 4.2 ...

  9. PHP基础之输出缓冲区基本概念、原理分析

    一.概念 在PHP运行的过程中,可以将会产生输出的函数或操作结果暂时保存在PHP的缓冲区,只有当缓冲区满了.或者PHP运行完毕.或者在必要时候进行输出,才会将数据输出到浏览器,此缓冲数据的区域称为PH ...

  10. Linux环境下安装RabbitMQ

    首先RabbitMQ是使用erLang编写的开源消息中间件.所以需要先安装erlang环境. 我使用的是CentOS的系统安装erlang21.0的步骤如下: #下载安装包 (下面是我用的比较匹配的版 ...