问题描述
为什么不先找遍文件,再找文件夹?
如上图所示,d.c文件查询完后,我认为继续查询文件list.c,而不是进入文件夹demo
附上深度目录查询代码
int SearchDepth( const char * Path , P_Node head )
{
int count = 0 ;
char TmpPath [257] = {0} ;
// 打开目录文件
DIR * fp = opendir( Path );
if ( NULL == fp )
{
// perror("open dir error");
fprintf( stderr , "open dir : %s error:%s\n" , Path , strerror(errno) );
return -1 ;
}
while(1)
{
// 读取目录项
struct dirent * dir = readdir( fp );
if (NULL == dir )
{
perror("read dir error");
break ;
}
bzero(TmpPath , 257); // 清空临时数组中的内容避免出现误会
if (dir->d_name[0] == '.') // 如果文件名字以 . 开头的则为隐藏文件, 选择直接忽略
{
continue;
}
else if ( dir->d_type == 4 ) // 检查是否为目录文件
{
// 把当前的路劲以及该目录文件的名字进行拼接作为递归下一个目录的完整路径
snprintf( TmpPath , 257 , "%s/%s" ,Path , dir->d_name );
/* 递归调用自己*/
count += SearchDepth( TmpPath , head );
}
else if ( dir->d_type == 8 )
{
snprintf( TmpPath , 257 , "%s/%s" ,Path , dir->d_name );
printf("遍历寻找到普通文件:%s\n" , TmpPath);
char * tmp = strrchr( dir->d_name , '.' ); // 在字符串 dir->d_name 找最后一个 . 的出现
if ( tmp == NULL ) // 当 tmp 指向NULL 的时候说明该文件路径名中没有出现后缀名
{
continue;
}
// 用新的文件名等信息创建一个新的节点
P_Node new = InitList( TmpPath , *(tmp+1) ); // .jpg .bmp .mp3 .avi ...
// 把新节点插入到链表中
Add2List( head , new );
count ++ ;
}
}
// 关闭目录文件
closedir(fp);
return count ;
}
原因分析:
与目录下文件排列顺序有关
深度目录查询的关键
1.readdir()查询成功返回下个目录进入点
2.根据dir->d_type的不同来区分是目录还是文件
当dir是目录时,dir->d_type = 4
当dir是文件时,dir->d_type = 8
根据d_type不同,判断是否递归查询自己
(dir指针指向读取文件的结构体)
解决方案:
直接把读取文件的结构体打印出来
printf( "Inod:%ld Off:%ld Reclen:%hd Type:%d Name:%s\n",
dir->d_ino , dir->d_off , dir->d_reclen , dir->d_type , dir->d_name);
readdir()是按文件偏移量来读取的,off为1、2是隐藏文件。
本例中,读到文件d.c后,下一个读文件夹demo,进入文件夹后再按文件偏移量来读取,读完文件夹demo中的文件后,输出read dir error: Success , 再从根目录下一个off读文件。
什么是"当前文件偏移量"?
每当打开一个文件都有一个"当前文件偏移量"(current file offset). 它通常是非负整数,用以度量从文件开始处计算的字节数.通常,读,写操作都是从当前文件偏移量开始,并使偏移量增加所读写的字节数.按照系统默认情况,当打开一个文件时,除非指定O_APPEND选项,否则该偏移量被设置为0.
参考链接:https://blog.csdn.net/weixin_45030544/article/details/115326371