使用C++遍历目录及其子目录,以vector形式获取所有文件。
大体思想是使用队列先广度遍历所有目录,得到所有目录后,在遍历每个目录,获取文件。
文件和目录都是以vector引用的形式返回,因此在使用前,不能释放类GetDirFiles。
程序在VS2013下验证过。
get_dir_files.h1
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.cpp1
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;
}