【转载】windows 递归遍历一个文件夹下面的所有文件


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     无该文件或目录

你可能感兴趣的:(【转载】windows 递归遍历一个文件夹下面的所有文件)