获取目录下的所有子目录和文件

使用C++遍历目录及其子目录,以vector形式获取所有文件。

  • 相要获取某一目录下的所有子目录以及文件。把结果放到vector中,且以引用形式返回,所以在使用前,不要销毁对象。

大体思想是使用队列先广度遍历所有目录,得到所有目录后,在遍历每个目录,获取文件。
文件和目录都是以vector引用的形式返回,因此在使用前,不能释放类GetDirFiles
程序在VS2013下验证过。
get_dir_files.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifndef __GETDIRFILES__H__
#define __GETDIRFILES__H__
#include <vector>
#include <string>
using namespace std;
class GetDirFiles
{
public:
GetDirFiles();
bool SetRootDir( const char* _dir );
void SetFileSpec(const char* _file_spec);
void GetAll();
vector<string>& GetFilesVector();
vector<string>& GetDirsVector();
protected:
void GetAllDirs();//获取所有目录
void GetAllFiles();//获取当前目录下的文件
private:
char dir[_MAX_PATH];
string file_spec;
vector<string> v_dirs;
vector<string> v_files;
bool done;//用来标记是否已经获取所有目录和文件

};
#endif

get_dir_files.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "get_dir_files.h"

#include <direct.h>
#include <io.h>
#include <deque>
#include <iostream>
using namespace std;
GetDirFiles::GetDirFiles()
{
_getcwd(dir, _MAX_PATH);
size_t len = strlen(dir);
if ('\\' != dir[len - 1])
strcat(dir, "\\");
file_spec = "*.*";//默认是筛选全部文件
done = false;
}
bool GetDirFiles::SetRootDir(const char* _dir)
{
//dir转为绝对路径
if( NULL == _fullpath(dir, _dir, _MAX_PATH))
return false;
//判断目录是否存在
if (0 != _chdir(dir))
{
cout << "dir:[" << dir << "] doesn't exist";
return false;
}

//目录最后一个字母必须是'\'
size_t len = strlen(dir);
if ('\\' != dir[len - 1])
strcat(dir, "\\");
done = false;
return true;
}
void GetDirFiles::SetFileSpec(const char* _file_spec)
{
file_spec = _file_spec;
}
void GetDirFiles::GetAll()
{
if (done)
return;
done = true;
v_dirs.clear();
v_files.clear();
GetAllDirs();
GetAllFiles();

}
vector<string>& GetDirFiles::GetFilesVector()
{
if (!done)
GetAll();
return v_files;
}
vector<string>& GetDirFiles::GetDirsVector()
{
if (!done)
GetAll();
return v_dirs;
}
void GetDirFiles::GetAllFiles()
{
if (!done)
GetAll();

_finddata_t file_info;
intptr_t handle;
char current_dir[_MAX_PATH];
char file_name[_MAX_PATH];
for(vector<string>::iterator iter = v_dirs.begin(); iter != v_dirs.end(); ++iter)
{
strcpy(current_dir, (*iter).c_str());
_chdir(current_dir);
if (-1 != (handle = _findfirst(file_spec.c_str(), &file_info)))
{
do
{
if (!(file_info.attrib & _A_SUBDIR))//不是目录
{
strcpy(file_name, current_dir);
strcat(file_name, file_info.name);
v_files.push_back(file_name);
}
} while (0 == _findnext(handle, &file_info));
_findclose(handle);
}
}

}
void GetDirFiles::GetAllDirs()
{
v_dirs.clear();
deque<string> d_dirs;
d_dirs.push_back(dir);
v_dirs.push_back(dir);
char current_dir[_MAX_PATH];
char sub_dir[_MAX_PATH];
_finddata_t file_info;
intptr_t handle;
while (!d_dirs.empty())
{
string tmp = d_dirs.front();
d_dirs.pop_front();
strcpy( current_dir, tmp.c_str());
_chdir(current_dir);//更改当前工作目录
if (-1 != (handle = _findfirst("*.*", &file_info)))
{
do
{
if ((file_info.attrib & _A_SUBDIR))//是目录
{
if (0 != strcmp(file_info.name, ".")//不是当前目录和上级目录
&& 0 != strcmp(file_info.name, ".."))
{
strcpy(sub_dir, current_dir);//先添加当前目录
strcat(sub_dir, file_info.name);//添加目录
strcat(sub_dir, "\\");
d_dirs.push_back(sub_dir);
v_dirs.push_back(sub_dir);
}
}
} while (0 == _findnext(handle, &file_info));
_findclose(handle);
}
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "get_dir_files.h"
#include <iostream>
int main()
{

GetDirFiles get_dir_file;
get_dir_file.SetRootDir("D:");
vector<string> files = get_dir_file.GetFilesVector();
for (vector<string>::iterator iter = files.begin(); iter != files.end(); ++iter)
{
std::cout << *iter << std::endl;
}
return 0;
}

文章目录
,
#add by kangyabing