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);elsesprintf(temp, "%s%s", path.c_str(), direntry->d_name);if (stat(temp, &st) == 0){#ifdef WIN32if((st.st_mode&_S_IFDIR) == _S_IFDIR) { if(recursive){traverse_dir(temp,files,recursive, includedir);}}#elseif (S_ISDIR(st.st_mode)){if (recursive){traverse_dir(temp, files, recursive);}}#endifelse{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 無該檔案或目錄