最近学了IO编程方面,就想用IO编程来检索出一个文件夹里面所有的文件:
具体实现过程:就是利用目录文件判断来通过不断递归调用,不断将目录里面的文件搜索出来,并将搜索到的普通文件名和文件大小以链表方式保存。
参考代码:
/* 2、读取一个目录里面所有的文件(包括它的子目录里面的文件),并打印出来(递归)
(把所有文件名插入到链表) */
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <dirent.h>
#include <stdlib.h>
#include <sys/types.h>
#include "kernel_list.h"
typedef struct filename
{
char name[256];
unsigned short fsize;
unsigned char type;
struct list_head small_list;
}FILENAME,*FILE_PTR;
FILE_PTR Init_list();//初始化链表
FILE_PTR Creat_node(struct dirent *dir);//创建节点
int Insert_newnode_to_list(FILE_PTR head,FILE_PTR newnode);//将节点插入到链表中
int show_file(FILE_PTR head);//全部显示文件名
int show_all_file(FILE_PTR head,const char *path);
int main(int argc,const char **argv)
{
FILE_PTR head = Init_list();
if(argc != 2)
{
printf("请输入路径:\n");
return -1;
}
show_all_file(head,argv[1]);
show_file(head);
return 0;
}
int show_all_file(FILE_PTR head,const char *path)
{
char PATH[256];
bzero(PATH,256);
DIR *DIR_fp = opendir(path);
if(DIR_fp == NULL)
{
fprintf(stderr,"open %s error:%s",path,strerror(errno));
return -1;
}
while(1)
{
strcpy(PATH,path);
strcat(PATH,"/");
struct dirent *dir = readdir(DIR_fp);
if(dir == NULL)//如果到文件最后就退出该文件
{
printf("file finshed\n");
break;
}
if(strcmp(dir->d_name,".")==0 || strcmp(dir->d_name,"..")==0)//跳过两个隐藏文件
{
continue;
}
if(dir->d_type == DT_DIR)
{
strcat(PATH,dir->d_name);
show_all_file(head,PATH);
bzero(PATH,256);
}
else
{
FILE_PTR newnode = Creat_node(dir);
Insert_newnode_to_list(head,newnode);
}
}
closedir(DIR_fp);
return 0;
}
FILE_PTR Creat_node(struct dirent *dir)
{
FILE_PTR newnode = calloc(1,sizeof(FILENAME));
if(newnode == NULL)
{
printf("creat newnode error!\n");
return NULL;
}
strcpy(newnode->name,dir->d_name);
newnode->fsize = dir->d_reclen;
newnode->type = dir->d_type;
INIT_LIST_HEAD(&newnode->small_list);
return newnode;
}
//初始化链表
FILE_PTR Init_list()
{
FILE_PTR head = calloc(1,sizeof(FILENAME));
if(head == NULL)
{
printf("Init list error\n");
return NULL;
}
INIT_LIST_HEAD(&head->small_list);
return head;
}
//将节点插入到链表中
int Insert_newnode_to_list(FILE_PTR head,FILE_PTR newnode)
{
if(head == NULL || newnode == NULL)
{
printf("file open error!\n");
return -1;
}
list_move_tail(&newnode->small_list,&head->small_list);//尾插法
return 0;
}
//遍历显示链表
int show_file(FILE_PTR head)
{
if(head == NULL)
{
printf("error");
return -1;
}
struct list_head *pos = NULL;
list_for_each(pos,&head->small_list)
{
FILE_PTR node = list_entry(pos,FILENAME,small_list);//把小结构体转为大结构体地址
printf("filename:%s\n",node->name);
printf("filesize:%hu\n",node->fsize);
printf("filetype:%u\n",node->type);
printf("\n");
}
return 0;
}
/*
实现如同Linux中tree脚本功能效果
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
int flag ; //全局变量默认为0
int my_tree(const char *file);
int main(int argc,const char **argv)
{
if(argc < 2)
{
printf("pls input directory!\n");
return -1;
}
printf("\033[1m\033[45;33m %s \033[0m\n",argv[1]);
my_tree(argv[1]);
return 0;
}
int my_tree(const char *file)
{
flag++;
DIR *dir_fp = opendir(file);
if(dir_fp == NULL)
{
chdir(".."); //退出目录前返回上一级目录返回上一级目录
flag --;
//printf("opendir failed!\n");
return -1;
}
struct dirent *dir_stu = NULL;
while(1)
{
dir_stu = readdir(dir_fp);
if(dir_stu == NULL)
{
flag--;
break;
}
if(!strcmp(dir_stu->d_name,"..") || !strcmp(dir_stu->d_name,"."))//跳过两个隐藏文件
{
continue;
}
int i;
for(i=0;i<flag;i++)
{
printf(" |-");
}
if(dir_stu->d_type == DT_DIR)
{
printf("\033[1m\033[45;33m %s \033[0m\n",dir_stu->d_name);
//printf("%s\n",dir_stu->d_name);
chdir(dir_stu->d_name); //进入当前名目录
my_tree(".");
}
else
{
printf("%s\n",dir_stu->d_name);
}
}
closedir(dir_fp);
return 0;
}
注意:引入chdir()函数,这个函数可以通过字符串进入响应的目录不需要再通过字符串拼接实现