zoukankan      html  css  js  c++  java
  • 递归遍历一个文件夹下面的所有文件

    traverse_dir.h

    #ifndef TRAVERSE_DIR_H
    #define TRAVERSE_DIR_H
    
    #include <vector>
    #include <string>
    using namespace std;
    
    #ifdef   _WIN32   
    #include   <io.h>   
    #include   <sys/types.h>   
    #else
    #include <dirent.h>
    #endif  
    
    #define   _MAX_FNAME   256  
    
    #ifdef   _WIN32   
    
    struct   dirent   
    {   
    	long   d_ino;   
    	off_t   d_off;     
    	unsigned   short   d_reclen;   
    	char   d_name[_MAX_FNAME+1];   
    };   
    
    typedef   struct   
    {   
    	long   handle;                               
    	short   offset;                             
    	short   finished;                         
    	struct   _finddata_t   fileinfo;   
    	char   *dir;                                       
    	struct   dirent   dent;                     
    }   DIR;   
    
    DIR*     opendir(const   char   *);   
    struct   dirent   *   readdir(DIR   *);   
    int   closedir(DIR   *);
    #endif  
    
    int traverse_dir(string path,vector<string>& files,bool recursive = false,bool includedir = false);
    
    #endif
    

      

    traverse_dir.cpp

    #include   <stdio.h>   
    #include   <fcntl.h>   
    #include   <sys/types.h>
    #include   <ctype.h> 
    #include   <stdlib.h>
    #include   <errno.h>
    #include   <sys/stat.h>
    #include   "traverse_dir.h"
    
    #ifdef   _WIN32   
    DIR*   opendir(const   char   *dir)   
    {   
    	DIR   *dp;   
    	char   filespec[_MAX_FNAME];   
    	long   handle;   
    	int   index;   
    	strncpy(filespec,   dir   ,_MAX_FNAME);   
    	index   =   strlen(filespec)   -   1;   
    	if   (index   >=   0   &&   (filespec[index]   ==   '/'   ||   filespec[index]   ==   '\\'))   
    		filespec[index]   =   '\0';   
    	strcat(filespec,   "/*");   
    	dp   =   (DIR   *)malloc(sizeof(DIR));   
    	dp->offset   =   0;   
    	dp->finished   =   0;   
    	dp->dir   =   strdup(dir);   
    	if   ((handle   =   _findfirst(filespec,   &(dp->fileinfo)))   <   0)     
    	{   
    		if   (errno   ==   ENOENT)   
    			dp->finished   =   1;   
    		else   
    			return   NULL;   
    	}   
    	dp->handle   =   handle;   
    	return   dp;   
    }   
    
    struct   dirent*   readdir(DIR   *dp)   
    {   
    	if   (!dp   ||   dp->finished)     
    		return   NULL;   
    	if   (dp->offset   !=   0)     
    	{   
    		if   (_findnext(dp->handle,   &(dp->fileinfo))   <   0)     
    		{   
    			dp->finished   =   1;   
    			return   NULL;   
    		}   
    	}   
    	dp->offset++;   
    	strncpy(dp->dent.d_name,   dp->fileinfo.name,   _MAX_FNAME);   
    	dp->dent.d_ino   =   1;   
    	dp->dent.d_reclen   =   strlen(dp->dent.d_name);   
    	dp->dent.d_off   =   dp->offset;   
    	return   &(dp->dent);   
    }   
    
    int   closedir(DIR   *dp)   
    {   
    	if   (!dp)     
    		return   0;   
    	_findclose(dp->handle);   
    	if(dp->dir)     
    	{   
    		free(dp->dir);   
    		dp->dir=NULL;   
    	}   
    	if(dp)     
    	{   
    		free(dp);   
    		dp=NULL;   
    	}   
    	return   0;   
    }
    #endif  
    
    int traverse_dir(string path,vector<string>& files,bool recursive,bool includedir)
    {
    	if (path.empty())
    		return -1;
    	DIR* dir;
    	dir = opendir(path.c_str());
    	if (dir == NULL)
    		return -2;
    	struct dirent *direntry;
    	struct stat st;
    
    	char temp[256] = {0};
    	while (direntry = readdir(dir))
    	{
    		if (!strcmp(direntry->d_name, ".") || !strcmp(direntry->d_name, ".."))
    			continue;
    
    		if(path[path.size()-1] != '/')
    			sprintf(temp, "%s/%s", path.c_str(), direntry->d_name);
    		else
    			sprintf(temp, "%s%s", path.c_str(), direntry->d_name);
    
    
    		if (stat(temp, &st) == 0)
    		{
    #ifdef WIN32
    			if((st.st_mode&_S_IFDIR) == _S_IFDIR)   
    			{   
    				if(recursive)
    				{					
    					traverse_dir(temp,files,recursive, includedir);
    				}
    			}
    #else
    			if (S_ISDIR(st.st_mode))
    			{
    				if (recursive)
    				{					
    					traverse_dir(temp, files, recursive);
    				}
    			}
    #endif
    			else
    			{
    				if(includedir)
    					files.push_back(temp);
    				else
    				{
    					string file = temp;
    					files.push_back(file.substr(file.find_last_of('/') + 1));//only need file name
    				}				
    			}
    		}
    	}
    	closedir(dir);
    	return (int)files.size();
    
    }
    

      

    main.cpp

    int main()
    {
    	std::string strDir = "F:\\HGUI\\HGUI";
    	std::vector<std::string> vec;
    	int ret = traverse_dir(strDir, vec, true, true);
    	for (int i=0; i<vec.size(); ++i)
    	{
    		cout<<vec[i]<<endl;
    	}
    	return 0;
    }
    

      

    1 . int _access( const char *path, int mode );
    功   能 : 测定文件/目录存取权限.
    头文件 : #include <io.h>
    参   数 : path:文件或者目录
       mode:权限设定,其值如下:
       00 Existence only 
       02 Write permission 
       04 Read permission 
       06 Read and write permission

    返回值 : 拥有该权限返回0
       没有权限返回-1,且设置errno为如下值
       ENOENT 路径/文件不存在
       EACCES 没有相应权限

    2 . int _chdir( const char *dirname );
    功   能 : 更改当前工作目录.
    头文件 : #include <direct.h>
    返回值 : 成功返回0
       失败返回-1,且设置errno如下:
       ENOENT 该路径不存在

    3 . int _chdrive( int drive );
    功   能 : 更改当前工作驱动器.
    头文件 : #include <direct.h>
    返回值 : 成功返回0
       失败返回-1
    注   释 : 参数说明
         drive =1<==> A盘
         drive =2<==> B盘
         drive =3<==> C盘
       如此等等,该函数可以由_chdir代替

    4 . int _findclose( long handle );
    功   能 : 关闭搜寻句柄并释放相应资源
    头文件 : #include <io.h>
    参   数 : long handle 搜索句柄(通常由紧靠其前的_findfirst()返回,_findfirst()见下)
       fileinfo 文件信息buffer
    返回值 : 成功返回0
       出错返回-1,且设置errno为如下值
       ENOENT 没有更多的符合该泛式的文件

    5 . long _findfirst( char *filespec, struct _finddata_t *fileinfo );
    功   能 : 提供与filespec指定入口泛式匹配的第一个文件.通常后继用_findnext函数后续使用来完成某泛式下的文件遍历.
    头文件 : #include <io.h>
    参   数 : filespec 目标文件规范,可以包含通配符
       fileinfo 文件信息buffer
    返回值 : 成功返回唯一的搜索句柄
       出错返回-1,且设置errno为如下值
       ENOENT 该泛式无法匹配
       EINVAL 无效文件名

    6 . int _findnext( long handle, struct _finddata_t *fileinfo );
    功   能 : 按照前面_findfirst中的泛式规则,查找下一个符合该泛式的文件,并以 此为依据修改fileinfo中的值
    头文件 : #include <io.h>
    参   数 : long handle 搜索句柄(通常由紧靠其前的_findfirst()返回)
       fileinfo 文件信息buffer
    返回值 : 成功返回0
       出错返回-1,且设置errno为如下值
       ENOENT 没有更多的符合该泛式的文件

    7 . char *_getcwd( char *buffer, int maxlen );
    功   能 : 获得当前工作目录.
    头文件 : #include <direct.h>
    返回值 : 成功返回指向buffer的pointer
       失败返回NULL,且设置errno为以下三个值之一:
       ENODEV 无该设备
       ENOMEM 内存不够
       ERANGE 结果超出范围
    注   意 : 当第一个参数为 NULL 时,第二个参数 maxlen 长度设置无效,且函数使用malloc分配足够内存,需要将函数返回值传递给free()函数来释放内存.
       当第一个参数不为 NULL 时,maxlen 指定长度不够函数返回错,设置errno为ERANGE

    8 . char *_getdcwd( int drive, char *buffer, int maxlen );
    功   能 : 获得指定驱动器的当前工作路径.
    头文件 : #include <direct.h>
    返回值 : 成功返回指向buffer的pointer
       失败返回NULL,且设置errno为以下三个值之一:
       ENODEV 无该设备
       ENOMEM 内存不够
       ERANGE 结果超出范围
    注   意 : 当第一个参数为 NULL 时,该函数设置errno为ERANGE

    9 . int _getdrive( void );
    功   能 : 获得当前磁盘驱动器.
    头文件 : #include <direct.h>
    返回值 : 返回驱动器值,1<==>A 2<==>B 如此等等;函数不会出错!

    10 . unsigned long _getdrives(void);
    功   能 : 获得当前所有驱动器.
    头文件 : #include <direct.h>
    返回值 : 各个位代表对应驱动器,
       bit 0 <==> A
       bit 1 <==> B
       bit 2 <==> C
       ... ...
    注:bit x 表示unsigned long的第x位

    11 . int _mkdir( const char *dirname );
    功   能 : 创建一个新目录,目录名为dirname.
    头文件 : #include <direct.h>
    返回值 : 成功返回0
       失败返回-1,且设置errno为以下三个值之一
       EACCESS 权限不允许
       EEXIST   该目录已存在
       ENOENT   无该文件或目录

    12 . int _rmdir( const char *dirname );
    功   能 : 删除名为dirname的目录.
    头文件 : #include <direct.h>
    返回值 : 成功返回0
       失败返回-1,且设置errno为以下三个值之一
       EACCESS    权限不允许
       ENOTEMPTY dirname不是文件夹;
          或者该文件夹不空;
          或者dirname为当前工作文件夹;
          或者dirname为当根文件夹;
       ENOENT     无该文件或目录

  • 相关阅读:
    vue 组件轮播联动
    Echarts 解决饼图文字过长重叠的问题
    Echarts 背景渐变柱状图
    vue 组件间数据传递
    vue webpack build 打包过滤console.log()日志
    自定义字段排序
    vue 路由嵌套高亮问题
    微信小程序验证码获取倒计时
    解决小程序里面的图片之间有空隙的问题???
    axios使用
  • 原文地址:https://www.cnblogs.com/kex1n/p/2258478.html
Copyright © 2011-2022 走看看