题目如下:
实现linux下tree的单一功能[只打印目录个数和文件个数(不包含隐藏文件)]
首选我们介绍几个相关的linux 系统API
函数名函数描述函数声明
opendir打开一个目录,成功返回一个DIR*类型指针,失败返回NULLDIR* opendir(const char* name)
readdir读取打开的目录下的子成员,成功返回结构体指针,否则返回NULLstruct dirent* readdir(DIR* dir)
closedir关闭已打开的目录.成功返回0,失败返回-1int closedir(DIR* dirp)struct dirent 结构体
#include //所需要包含头文件
struct dirent{
ino_t d_ino; //索引[inode]编号
off_t d_off; //在目录文件中的偏移
unsigned short d_reclen; //文件名长度
unsigned char d_type; //文件类型
char d_name[256]; //文件名
}
d_type 应对的所有文件类型
DT_BLK 块设备
DT_CHR 字符设备
DT_DIR 目录
DT_FIFO 有名管道
DT_LNK 符号链接(软链接)
DT_REG 普通文件
DT_SOCK socket套接字
DT_UNKNOWN 未知类型
注意事项:
l.linux目录下有 . 和 .. 分别代表指向当前目录和上一级目录,不处理会造成死循环
2. 不包含隐藏文件,需要将普通文件以.开头的以忽略处理
代码如下:
#include //输入输出头文件
#include //eixt()函数头文件
#include //unix标准库头文件
#include //opendir() closedir() readdir()所需头文件
#include //同上
#include //字符串常用API头文件
//功能函数
//成功返回EXIT_SUCCESS
//失败返回EXIT_FAILURE
int myTree(const char* root, unsigned int* const dirs, unsigned int* const files){
int ret = EXIT_SUCCESS;//返回值
DIR* dir = NULL; //打开的目录
char path[1024] = { 0 };//拼接文件相对路径使用
struct dirent* ptr = NULL; //读取的目录下子成员结构体
//判断参数
if(NULL == root || NULL == dirs || NULL == files){
//错误提示
printf("func %s err:[NULL == root || NULL == dirs || NULL == files]", __FUNCTION__);
//直接退出
ret = EXIT_FAILURE;
goto END;
}
//打开目录
dir = opendir(root);
//判断是否打开失败
if(NULL == dir){
//友情错误提示
perror("func tree->opendir error: ");
ret = EXIT_FAILURE;
goto END;
}
//循环遍历目录下的文件成员
while(NULL != (ptr = readdir(dir))){
//判断是否是 . 和 .. 目录,或.开头的隐藏文件
if(0 == strncmp(ptr->d_name, ".", 1) || 0 == strcmp(ptr->d_name, "..")){
continue; //跳过处理
}
//如果是目录
if(DT_DIR == ptr->d_type){
(*dirs)++; //目录个数+1
sprintf(path, "%s/%s", root, ptr->d_name);
myTree(path, dirs, files);
}else{
(*files)++;
}
}
END:
//判断目录是否已关闭
if(NULL != dir){
closedir(dir);
dir = NULL;
}
return ret;
}
//主函数
int main(int argc, char* argv[]){
unsigned int dirs = 0; // 统计目录个数
unsigned int files = 0; // 统计文件个数
//判断命令行参数
if(2 > argc){
//没有参数,默认统计当前目录下
myTree(".", &dirs, &files);
}
else{
int i = 0;
//多个参数的情况下
for(i = 1; i < argc; i++){
myTree(argv[i], &dirs, &files);
}
}
//输出最后统计信息
printf("%d directories, %d files\n", dirs, files);
return EXIT_SUCCESS;
}