我的目标是:“让我的家人过得更好”
9、读取目录
//myls.c 递归读取目录下的所有文件 并统计结果
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<dirent.h>
#include<stdlib.h>
#include<string.h>
static int dir_num = 0; //目录个数
static int reg_num = 0;//普通文件个数
static int link_num = 0;//符号链接个数
static int fifo_num = 0;//管道文件个数
static int blk_num = 0;//块设备文件个数
static int chr_num = 0;//字符设备文件个数
//定义一个路径的最大长度
#define MY_MAXPATH 2048
void list(char * path, struct stat *stat)
{
if(path == 0 || stat == 0)
return ;
int pathlen = strlen(path);
struct dirent * dir = 0;
if(pathlen >= MY_MAXPATH)
return;
//判断文件类型
if(S_ISREG(stat->st_mode)){ reg_num++;printf("reg: %s/n",path);}
else if(S_ISBLK(stat->st_mode)){ blk_num++;printf("blk: %s/n",path);}
else if(S_ISCHR(stat->st_mode)) {chr_num++;printf("chr: %s/n",path);}
else if(S_ISFIFO(stat->st_mode)) {fifo_num++;printf("fifo: %s/n",path);}
else if(S_ISLNK(stat->st_mode)) {link_num++;printf("link:%s/n",path);}
else if(S_ISDIR(stat->st_mode))
{
dir_num++;
printf("dir: %s/n",path);
if(*(path+strlen(path) -1 ) == '/')
*(path+strlen(path) -1) = 0;
//取得下一层的目录的路径
*(path+pathlen) = '/';
*(path+pathlen+1) = 0;
char *ptr = path+pathlen+1;
DIR * d = opendir(path);
if(d == NULL)
return ;
struct stat stat;
//循环读取目录文件
dir = readdir(d);
while(dir != NULL)
{
//如果是.和.跳过
if(strcmp(dir->d_name,".") == 0)
{
printf("%s./n",path);
dir = readdir(d);
continue;
}
else if(strcmp(dir->d_name,"..") == 0)
{
printf("%s../n",path);
dir = readdir(d);
continue;
}
strcpy(ptr,dir->d_name);
if(lstat(path,&stat) < 0)
{
printf("========================/n");
perror("lstat");
continue;
}
else list(path,&stat); //递归调用下一层文件
dir = readdir(d);
}
}
return ;
}
//数据统计函数
void statistics()
{
int total = reg_num + dir_num + blk_num + chr_num + link_num + fifo_num;
printf("total file: %d/n", total);
printf("reg: %d , %f/n", reg_num , (double)reg_num/total);
printf("dir: %d , %f/n", dir_num , (double)dir_num/total);
printf("blk: %d , %f/n", blk_num , (double)blk_num/total);
printf("chr: %d , %f/n", chr_num , (double)chr_num/total);
printf("link: %d , %f/n", link_num , (double)link_num/total);
printf("fifo: %d , %f/n", fifo_num , (double)fifo_num/total);
}
int main(int argc, char * argv[])
{
if(argc != 2)
{
printf("usage:program path/n");
exit(0);
}
//分配内存存储路径字符串
char *path = malloc(sizeof(char)*MY_MAXPATH);
struct stat stat;
strcpy(path,argv[1]);
if(*(path+strlen(path) -1 ) == '/')
*(path+strlen(path) -1) = 0;
if(lstat(path,&stat) < 0) { perror(path); exit(1); }
list(path,&stat);//递归便利整个目录
free(path);
statistics();
}
运行:
white@white-desktop:/home/junjun/apue/chapter4$ ./a.out .
dir: .
./.
reg: ./linkTest.c
reg: ./test
reg: ./a.out
./a.out..
reg: ./core
reg: ./testumask0
reg: ./4-2.out
reg: ./myls.c
reg: ./tmpfileTest.c
reg: ./testumask1
reg: ./4-2.c
reg: ./testCat.c
reg: ./4-1.c
total file: 13
reg: 12 , 0.923077
dir: 1 , 0.076923
blk: 0 , 0.000000
chr: 0 , 0.000000
link: 0 , 0.000000
fifo: 0 , 0.000000
white@white-desktop:/home/junjun/apue/chapter4$