Linux Advance--目录下文件类型统计
2015-11-23 21:52
603 查看
统计目录下的文件类型需要读目录,相关的函数声明如下:
目录结构体定义如下:
下面是递归降序遍历目录层次结构,并按文件类型计数代码:
测试运行结果:
#include <dirent.h> DIR *opendir(const char *pathname); struct dirent *readdir(DIR *dp); void rewinddir(DIR *dp); int closedir(DIR *dp); long telldir(DIR *dp); void seekdir(DIR *dp, long loc);
目录结构体定义如下:
struct dirent { ino_t d_ino; /* i-node number */ char d_name[NAME_MAX + 1]; /* null-terminated filename */ };
下面是递归降序遍历目录层次结构,并按文件类型计数代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <dirent.h> #include <limits.h> #include <sys/stat.h> typedef int Myfunc(const char *, const struct stat *, int); static Myfunc myfunc; static int myftw(char *, Myfunc *); static int dopath(Myfunc *); char * path_alloc(int *); static long nreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot; int main(int argc, char *argv[]) { int ret; if (argc != 2) { printf("usage: ftw <starting-pathname>\n"); exit(1); } 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); } /* * Descend through the hierarchy, starting at "pathname". * The caller's func() is called for every file. */ #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; /* contains full pathname for every file */ static int myftw(char *pathname, Myfunc *func) { int len; fullpath = path_alloc(&len); /* malloc's for PATH_MAX+1 bytes */ strncpy(fullpath, pathname, len); fullpath[len-1] = 0; return (dopath(func)); } /* * Descend through the hierarchy, starting at "fullpath". * If "fullpath" is anything other than a directory, we lstat() it, * call func(), and return. For a directory, we call ourself * recursively for each name in the directory. */ static int dopath(Myfunc *func) { struct stat statbuf; struct dirent *dirp; DIR *dp; int ret; char *ptr; if (lstat(fullpath, &statbuf) < 0) /* stat error */ return func(fullpath, &statbuf, FTW_NS); if (S_ISDIR(statbuf.st_mode) == 0) /* not a directory */ return func(fullpath, &statbuf, FTW_F); /* * It's a directory. First call func() for the directory, * then process each filename in the directory. */ if (ret = func(fullpath, &statbuf, FTW_D) != 0) return ret; ptr = fullpath + strlen(fullpath); /* point to end of fullpath */ *ptr++ = '/'; *ptr = 0; if ((dp = opendir(fullpath)) == 0) /* can't read directory */ return func(fullpath, &statbuf, FTW_DNR); while ((dirp = readdir(dp)) != 0) { if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0) continue; /* ignore dot and dot-dot */ strcpy(ptr, dirp->d_name); /* append name after slash */ if ((ret = dopath(func)) != 0) /* recursive */ break; /* time to leave */ } ptr[-1] = 0; /* erase everything from slash onwards */ if (closedir(dp) < 0) { printf("can't close directory %s\n", fullpath); exit(1); } 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: printf("for S_IFDIR for %s\n", pathname); /* directories should have type = FTW_D */ exit(1); } break; case FTW_D: ndir++; break; case FTW_DNR: printf("can't read directory %s\n", pathname); break; case FTW_NS: printf("stat error for %s\n", pathname); break; default: printf("unknown type %d for pathname %s\n", type, pathname); } return 0; } char *path_alloc(int *sizep) { char *ptr; int size; size = 4096; if ((ptr = malloc(size)) == 0) { printf("malloc error for pathname\n"); exit(1); } if (sizep != 0) *sizep = size; return ptr; }
测试运行结果:
相关文章推荐
- 11个让你吃惊的 Linux 终端命令
- Linux默认配置文件系统路径 文件包含漏洞
- linux 软中断和tasklet
- mac安装linux虚拟机
- Linux进程管理
- 全面解析Linux 内核 3.10.x - 板级初始化 - setup_arch
- Linux 进程管理
- centOS安装git最新版
- centos 中如何将python更新到最新的版本
- OpenCV在Linux上的安装及初试
- Linux_RAID
- linux SPI总线驱动(一)
- linux下字符串处理工具二:awk(1)
- 关闭CentOS的错误提示音
- Linux 技巧:让进程在后台可靠运行的几种方法
- kali-linux安装后的一些配置
- Linux系统下对树莓派镜像进行烧写操作。可搭建自己的迷你服务器
- Linux-CentOS安装mysql5.6
- Linux安装jdk1.8
- linux下C++对线程的封装