服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++遍历文件夹下所有文件的多种方法

C++遍历文件夹下所有文件的多种方法

2021-06-20 15:46C++教程网 C/C++

这篇文章主要介绍了C++遍历文件夹下所有文件的多种方法,需要的朋友可以参考下

为数不多的好用的代码,遍历文件夹获取所有子文件名,"filespec"可用通配符“*?”。注意如果用相对路径的话,获取所有文件名后应再调用SetInitDir将初始目录改为当前目录,否则中间生成的文件都会放在之前的“InitDir”内。
C/C++遍历文件夹感觉真是很不好用,建议还是使用C/C++做单任务处理,然后通过脚本语言实现遍历比较合理。

CBrowseDir.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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <io.h>
#include <stdlib.h>
#include <direct.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
 
class CBrowseDir
{
protected:
  //存放初始目录的绝对路径,以'\'结尾
  char m_szInitDir[_MAX_PATH];
 
public:
  //缺省构造器
  CBrowseDir();
 
  //设置初始目录为dir,如果返回false,表示目录不可用
  bool SetInitDir(const char *dir);
 
  //开始遍历初始目录及其子目录下由filespec指定类型的文件
  //filespec可以使用通配符 * ?,不能包含路径。
  //如果返回false,表示遍历过程被用户中止
  bool BeginBrowse(const char *filespec);
  vector<string> BeginBrowseFilenames(const char *filespec);
 
protected:
  //遍历目录dir下由filespec指定的文件
  //对于子目录,采用迭代的方法
  //如果返回false,表示中止遍历文件
  bool BrowseDir(const char *dir,const char *filespec);
  vector<string> GetDirFilenames(const char *dir,const char *filespec);
  //函数BrowseDir每找到一个文件,就调用ProcessFile
  //并把文件名作为参数传递过去
  //如果返回false,表示中止遍历文件
  //用户可以覆写该函数,加入自己的处理代码
  virtual bool ProcessFile(const char *filename);
 
  //函数BrowseDir每进入一个目录,就调用ProcessDir
  //并把正在处理的目录名及上一级目录名作为参数传递过去
  //如果正在处理的是初始目录,则parentdir=NULL
  //用户可以覆写该函数,加入自己的处理代码
  //比如用户可以在这里统计子目录的个数
  virtual void ProcessDir(const char *currentdir,const char *parentdir);
};

CBrowseDir.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include "CBrowseDir.h"
 
CBrowseDir::CBrowseDir()
{
  //用当前目录初始化m_szInitDir
  getcwd(m_szInitDir,_MAX_PATH);
 
  //如果目录的最后一个字母不是'\',则在最后加上一个'\'
  int len=strlen(m_szInitDir);
  if (m_szInitDir[len-1] != '\\')
    strcat(m_szInitDir,"\\");
}
 
bool CBrowseDir::SetInitDir(const char *dir)
{
  //先把dir转换为绝对路径
  if (_fullpath(m_szInitDir,dir,_MAX_PATH) == NULL)
    return false;
 
  //判断目录是否存在
  if (_chdir(m_szInitDir) != 0)
    return false;
 
  //如果目录的最后一个字母不是'\',则在最后加上一个'\'
  int len=strlen(m_szInitDir);
  if (m_szInitDir[len-1] != '\\')
    strcat(m_szInitDir,"\\");
 
  return true;
}
 
vector<string> CBrowseDir::BeginBrowseFilenames(const char *filespec)
{
  ProcessDir(m_szInitDir,NULL);
  return GetDirFilenames(m_szInitDir,filespec);
}
 
bool CBrowseDir::BeginBrowse(const char *filespec)
{
  ProcessDir(m_szInitDir,NULL);
  return BrowseDir(m_szInitDir,filespec);
}
 
bool CBrowseDir::BrowseDir(const char *dir,const char *filespec)
{
  _chdir(dir);
 
  //首先查找dir中符合要求的文件
  long hFile;
  _finddata_t fileinfo;
  if ((hFile=_findfirst(filespec,&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果不是,则进行处理
      if (!(fileinfo.attrib & _A_SUBDIR))
      {
        char filename[_MAX_PATH];
        strcpy(filename,dir);
        strcat(filename,fileinfo.name);
        cout << filename << endl;
        if (!ProcessFile(filename))
          return false;
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  //查找dir中的子目录
  //因为在处理dir中的文件时,派生类的ProcessFile有可能改变了
  //当前目录,因此还要重新设置当前目录为dir。
  //执行过_findfirst后,可能系统记录下了相关信息,因此改变目录
  //对_findnext没有影响。
  _chdir(dir);
  if ((hFile=_findfirst("*.*",&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果是,再检查是不是 . 或 .. 
      //如果不是,进行迭代
      if ((fileinfo.attrib & _A_SUBDIR))
      {
        if (strcmp(fileinfo.name,".") != 0 && strcmp
          (fileinfo.name,"..") != 0)
        {
          char subdir[_MAX_PATH];
          strcpy(subdir,dir);
          strcat(subdir,fileinfo.name);
          strcat(subdir,"\\");
          ProcessDir(subdir,dir);
          if (!BrowseDir(subdir,filespec))
            return false;
        }
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  return true;
}
 
vector<string> CBrowseDir::GetDirFilenames(const char *dir,const char *filespec)
{
  _chdir(dir);
  vector<string>filename_vector;
  filename_vector.clear();
 
  //首先查找dir中符合要求的文件
  long hFile;
  _finddata_t fileinfo;
  if ((hFile=_findfirst(filespec,&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果不是,则进行处理
      if (!(fileinfo.attrib & _A_SUBDIR))
      {
        char filename[_MAX_PATH];
        strcpy(filename,dir);
        strcat(filename,fileinfo.name);
        filename_vector.push_back(filename);
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  //查找dir中的子目录
  //因为在处理dir中的文件时,派生类的ProcessFile有可能改变了
  //当前目录,因此还要重新设置当前目录为dir。
  //执行过_findfirst后,可能系统记录下了相关信息,因此改变目录
  //对_findnext没有影响。
  _chdir(dir);
  if ((hFile=_findfirst("*.*",&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果是,再检查是不是 . 或 .. 
      //如果不是,进行迭代
      if ((fileinfo.attrib & _A_SUBDIR))
      {
        if (strcmp(fileinfo.name,".") != 0 && strcmp
          (fileinfo.name,"..") != 0)
        {
          char subdir[_MAX_PATH];
          strcpy(subdir,dir);
          strcat(subdir,fileinfo.name);
          strcat(subdir,"\\");
          ProcessDir(subdir,dir);
          vector<string>tmp= GetDirFilenames(subdir,filespec);
          for (vector<string>::iterator it=tmp.begin();it<tmp.end();it++)
          {
            filename_vector.push_back(*it);
          }
        }
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  return filename_vector;
}
 
bool CBrowseDir::ProcessFile(const char *filename)
{
  return true;
}
 
void CBrowseDir::ProcessDir(const char
  *currentdir,const char *parentdir)
{
}

实现方法二、

数据分多个文件存储,读取数据就需要对多个文件进行操作。首先就需要定位到文件的名字,之后再对文件进行相应的读写操作。多次涉及多文件的读写操作,现将这个实现总结一下,方便自己和他人使用。具体代码如下:

?
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
#include "stdafx.h"
#include <stdio.h>
#include<iostream>
#include<vector>
#include <Windows.h>
#include <fstream> 
#include <iterator>
#include <string>
using namespace std;
 
#define MAX_PATH 1024 //最长路径长度
 
/*----------------------------
 * 功能 : 递归遍历文件夹,找到其中包含的所有文件
 *----------------------------
 * 函数 : find
 * 访问 : public 
 *
 * 参数 : lpPath [in]   需遍历的文件夹目录
 * 参数 : fileList [in]  以文件名称的形式存储遍历后的文件
 */
void find(char* lpPath,std::vector<const std::string> &fileList)
{
  char szFind[MAX_PATH];
  WIN32_FIND_DATA FindFileData;
   
  strcpy(szFind,lpPath);
  strcat(szFind,"\\*.*");
 
  HANDLE hFind=::FindFirstFile(szFind,&FindFileData);
  if(INVALID_HANDLE_VALUE == hFind)  return;
 
  while(true)
  {
    if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    {
      if(FindFileData.cFileName[0]!='.')
      {
        char szFile[MAX_PATH];
        strcpy(szFile,lpPath);
        strcat(szFile,"\\");
        strcat(szFile,(char* )(FindFileData.cFileName));
        find(szFile,fileList);
      }
    }
    else
    {
      //std::cout << FindFileData.cFileName << std::endl;
      fileList.push_back(FindFileData.cFileName);
    }
    if(!FindNextFile(hFind,&FindFileData))  break;
  }
  FindClose(hFind);
}
 
 
int main()
{
  std::vector<const std::string> fileList;//定义一个存放结果文件名称的链表
 
  //遍历一次结果的所有文件,获取文件名列表
  find("XXXX具体文件夹目录",fileList);//之后可对文件列表中的文件进行相应的操作
 
  //输出文件夹下所有文件的名称
  for(int i = 0; i < fileList.size(); i++)
  {
    cout << fileList[i] << endl;
  }
  cout << "文件数目:" << fileList.size() << endl;
  return 0;
}

测试了一下,目标文件夹下的文件名称存在了fileList容器中,根据读取的文件名称,可对文件进行相应的操作,输出结果如下所示:

C++遍历文件夹下所有文件的多种方法

c++ 遍历目录下文件方法三

function:遍历目录下所有文件,返回文件总数,子文件夹总数(修改一下可以获得全部文件名等)。

?
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#include "stdlib.h"
#include "direct.h"
#include "string.h"
#include "io.h"
#include "stdio.h" 
#include "iostream"
using namespace std;
 
class CBrowseDir
{
protected:
  //存放初始目录的绝对路径,以'\'结尾
  char m_szInitDir[_MAX_PATH];
 
public:
  //缺省构造器
  CBrowseDir();
 
  //设置初始目录为dir,如果返回false,表示目录不可用
  bool SetInitDir(const char *dir);
 
  //开始遍历初始目录及其子目录下由filespec指定类型的文件
  //filespec可以使用通配符 * ?,不能包含路径。
  //如果返回false,表示遍历过程被用户中止
  bool BeginBrowse(const char *filespec);
 
protected:
  //遍历目录dir下由filespec指定的文件
  //对于子目录,采用迭代的方法
  //如果返回false,表示中止遍历文件
  bool BrowseDir(const char *dir,const char *filespec);
 
  //函数BrowseDir每找到一个文件,就调用ProcessFile
  //并把文件名作为参数传递过去
  //如果返回false,表示中止遍历文件
  //用户可以覆写该函数,加入自己的处理代码
  virtual bool ProcessFile(const char *filename);
 
  //函数BrowseDir每进入一个目录,就调用ProcessDir
  //并把正在处理的目录名及上一级目录名作为参数传递过去
  //如果正在处理的是初始目录,则parentdir=NULL
  //用户可以覆写该函数,加入自己的处理代码
  //比如用户可以在这里统计子目录的个数
  virtual void ProcessDir(const char *currentdir,const char *parentdir);
};
 
CBrowseDir::CBrowseDir()
{
  //用当前目录初始化m_szInitDir
  getcwd(m_szInitDir,_MAX_PATH);
 
  //如果目录的最后一个字母不是'\',则在最后加上一个'\'
  int len=strlen(m_szInitDir);
  if (m_szInitDir[len-1] != '\\')
    strcat(m_szInitDir,"\\");
}
 
bool CBrowseDir::SetInitDir(const char *dir)
{
  //先把dir转换为绝对路径
  if (_fullpath(m_szInitDir,dir,_MAX_PATH) == NULL)
    return false;
 
  //判断目录是否存在
  if (_chdir(m_szInitDir) != 0)
    return false;
 
  //如果目录的最后一个字母不是'\',则在最后加上一个'\'
  int len=strlen(m_szInitDir);
  if (m_szInitDir[len-1] != '\\')
    strcat(m_szInitDir,"\\");
 
  return true;
}
 
bool CBrowseDir::BeginBrowse(const char *filespec)
{
  ProcessDir(m_szInitDir,NULL);
  return BrowseDir(m_szInitDir,filespec);
}
 
bool CBrowseDir::BrowseDir(const char *dir,const char *filespec)
{
  _chdir(dir);
 
  //首先查找dir中符合要求的文件
  long hFile;
  _finddata_t fileinfo;
  if ((hFile=_findfirst(filespec,&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果不是,则进行处理
      if (!(fileinfo.attrib & _A_SUBDIR))
      {
        char filename[_MAX_PATH];
        strcpy(filename,dir);
        strcat(filename,fileinfo.name);
        cout << filename << endl;
        if (!ProcessFile(filename))
          return false;
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  //查找dir中的子目录
  //因为在处理dir中的文件时,派生类的ProcessFile有可能改变了
  //当前目录,因此还要重新设置当前目录为dir。
  //执行过_findfirst后,可能系统记录下了相关信息,因此改变目录
  //对_findnext没有影响。
  _chdir(dir);
  if ((hFile=_findfirst("*.*",&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果是,再检查是不是 . 或 .. 
      //如果不是,进行迭代
      if ((fileinfo.attrib & _A_SUBDIR))
      {
        if (strcmp(fileinfo.name,".") != 0 && strcmp
          (fileinfo.name,"..") != 0)
        {
          char subdir[_MAX_PATH];
          strcpy(subdir,dir);
          strcat(subdir,fileinfo.name);
          strcat(subdir,"\\");
          ProcessDir(subdir,dir);
          if (!BrowseDir(subdir,filespec))
            return false;
        }
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  return true;
}
 
bool CBrowseDir::ProcessFile(const char *filename)
{
  return true;
}
 
void CBrowseDir::ProcessDir(const char
  *currentdir,const char *parentdir)
{
}
 
//从CBrowseDir派生出的子类,用来统计目录中的文件及子目录个数
class CStatDir:public CBrowseDir
{
protected:
  int m_nFileCount;  //保存文件个数
  int m_nSubdirCount; //保存子目录个数
 
public:
  //缺省构造器
  CStatDir()
  {
    //初始化数据成员m_nFileCount和m_nSubdirCount
    m_nFileCount=m_nSubdirCount=0;
  }
 
  //返回文件个数
  int GetFileCount()
  {
    return m_nFileCount;
  }
 
  //返回子目录个数
  int GetSubdirCount()
  {
    //因为进入初始目录时,也会调用函数ProcessDir,
    //所以减1后才是真正的子目录个数。
    return m_nSubdirCount-1;
  }
 
protected:
  //覆写虚函数ProcessFile,每调用一次,文件个数加1
  virtual bool ProcessFile(const char *filename)
  {
    m_nFileCount++;
    return CBrowseDir::ProcessFile(filename);
  }
 
  //覆写虚函数ProcessDir,每调用一次,子目录个数加1
  virtual void ProcessDir
    (const char *currentdir,const char *parentdir)
  {
    m_nSubdirCount++;
    CBrowseDir::ProcessDir(currentdir,parentdir);
  }
};
 
void main()
{
  //获取目录名
  char buf[256];
  printf("请输入要统计的目录名:");
  gets(buf);
 
  //构造类对象
  CStatDir statdir;
 
  //设置要遍历的目录
  if (!statdir.SetInitDir(buf))
  {
    puts("目录不存在。");
    return;
  }
 
  //开始遍历
  statdir.BeginBrowse("*.*");
  printf("文件总数: %d\n子目录总数:%d\n",statdir.GetFileCount(),statdir.GetSubdirCount());
}

已在windows上验证有效。

下面我加了BeginBrowseFilenames函数,以vector<char*>形式返回目录中所有文件名。

?
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#include "stdlib.h"
#include "direct.h"
#include "string.h"
#include "string"
#include "io.h"
#include "stdio.h" 
#include <vector>
#include "iostream"
using namespace std;
 
class CBrowseDir
{
protected:
  //存放初始目录的绝对路径,以'\'结尾
  char m_szInitDir[_MAX_PATH];
 
public:
  //缺省构造器
  CBrowseDir();
 
  //设置初始目录为dir,如果返回false,表示目录不可用
  bool SetInitDir(const char *dir);
 
  //开始遍历初始目录及其子目录下由filespec指定类型的文件
  //filespec可以使用通配符 * ?,不能包含路径。
  //如果返回false,表示遍历过程被用户中止
  bool BeginBrowse(const char *filespec);
  vector<string> BeginBrowseFilenames(const char *filespec);
 
protected:
  //遍历目录dir下由filespec指定的文件
  //对于子目录,采用迭代的方法
  //如果返回false,表示中止遍历文件
  bool BrowseDir(const char *dir,const char *filespec);
  vector<string> GetDirFilenames(const char *dir,const char *filespec);
  //函数BrowseDir每找到一个文件,就调用ProcessFile
  //并把文件名作为参数传递过去
  //如果返回false,表示中止遍历文件
  //用户可以覆写该函数,加入自己的处理代码
  virtual bool ProcessFile(const char *filename);
 
  //函数BrowseDir每进入一个目录,就调用ProcessDir
  //并把正在处理的目录名及上一级目录名作为参数传递过去
  //如果正在处理的是初始目录,则parentdir=NULL
  //用户可以覆写该函数,加入自己的处理代码
  //比如用户可以在这里统计子目录的个数
  virtual void ProcessDir(const char *currentdir,const char *parentdir);
};
 
CBrowseDir::CBrowseDir()
{
  //用当前目录初始化m_szInitDir
  getcwd(m_szInitDir,_MAX_PATH);
 
  //如果目录的最后一个字母不是'\',则在最后加上一个'\'
  int len=strlen(m_szInitDir);
  if (m_szInitDir[len-1] != '\\')
    strcat(m_szInitDir,"\\");
}
 
bool CBrowseDir::SetInitDir(const char *dir)
{
  //先把dir转换为绝对路径
  if (_fullpath(m_szInitDir,dir,_MAX_PATH) == NULL)
    return false;
 
  //判断目录是否存在
  if (_chdir(m_szInitDir) != 0)
    return false;
 
  //如果目录的最后一个字母不是'\',则在最后加上一个'\'
  int len=strlen(m_szInitDir);
  if (m_szInitDir[len-1] != '\\')
    strcat(m_szInitDir,"\\");
 
  return true;
}
 
vector<string> CBrowseDir::BeginBrowseFilenames(const char *filespec)
{
  ProcessDir(m_szInitDir,NULL);
  return GetDirFilenames(m_szInitDir,filespec);
}
 
bool CBrowseDir::BeginBrowse(const char *filespec)
{
  ProcessDir(m_szInitDir,NULL);
  return BrowseDir(m_szInitDir,filespec);
}
 
bool CBrowseDir::BrowseDir(const char *dir,const char *filespec)
{
  _chdir(dir);
 
  //首先查找dir中符合要求的文件
  long hFile;
  _finddata_t fileinfo;
  if ((hFile=_findfirst(filespec,&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果不是,则进行处理
      if (!(fileinfo.attrib & _A_SUBDIR))
      {
        char filename[_MAX_PATH];
        strcpy(filename,dir);
        strcat(filename,fileinfo.name);
        cout << filename << endl;
        if (!ProcessFile(filename))
          return false;
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  //查找dir中的子目录
  //因为在处理dir中的文件时,派生类的ProcessFile有可能改变了
  //当前目录,因此还要重新设置当前目录为dir。
  //执行过_findfirst后,可能系统记录下了相关信息,因此改变目录
  //对_findnext没有影响。
  _chdir(dir);
  if ((hFile=_findfirst("*.*",&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果是,再检查是不是 . 或 .. 
      //如果不是,进行迭代
      if ((fileinfo.attrib & _A_SUBDIR))
      {
        if (strcmp(fileinfo.name,".") != 0 && strcmp
          (fileinfo.name,"..") != 0)
        {
          char subdir[_MAX_PATH];
          strcpy(subdir,dir);
          strcat(subdir,fileinfo.name);
          strcat(subdir,"\\");
          ProcessDir(subdir,dir);
          if (!BrowseDir(subdir,filespec))
            return false;
        }
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  return true;
}
 
vector<string> CBrowseDir::GetDirFilenames(const char *dir,const char *filespec)
{
  _chdir(dir);
  vector<string>filename_vector;
  filename_vector.clear();
 
  //首先查找dir中符合要求的文件
  long hFile;
  _finddata_t fileinfo;
  if ((hFile=_findfirst(filespec,&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果不是,则进行处理
      if (!(fileinfo.attrib & _A_SUBDIR))
      {
        char filename[_MAX_PATH];
        strcpy(filename,dir);
        strcat(filename,fileinfo.name);
        filename_vector.push_back(filename);
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  //查找dir中的子目录
  //因为在处理dir中的文件时,派生类的ProcessFile有可能改变了
  //当前目录,因此还要重新设置当前目录为dir。
  //执行过_findfirst后,可能系统记录下了相关信息,因此改变目录
  //对_findnext没有影响。
  _chdir(dir);
  if ((hFile=_findfirst("*.*",&fileinfo)) != -1)
  {
    do
    {
      //检查是不是目录
      //如果是,再检查是不是 . 或 .. 
      //如果不是,进行迭代
      if ((fileinfo.attrib & _A_SUBDIR))
      {
        if (strcmp(fileinfo.name,".") != 0 && strcmp
          (fileinfo.name,"..") != 0)
        {
          char subdir[_MAX_PATH];
          strcpy(subdir,dir);
          strcat(subdir,fileinfo.name);
          strcat(subdir,"\\");
          ProcessDir(subdir,dir);
          vector<string>tmp= GetDirFilenames(subdir,filespec);
          for (vector<string>::iterator it=tmp.begin();it<tmp.end();it++)
          {
            filename_vector.push_back(*it);
          }
        }
      }
    } while (_findnext(hFile,&fileinfo) == 0);
    _findclose(hFile);
  }
  return filename_vector;
}
 
bool CBrowseDir::ProcessFile(const char *filename)
{
  return true;
}
 
void CBrowseDir::ProcessDir(const char
  *currentdir,const char *parentdir)
{
}
 
//从CBrowseDir派生出的子类,用来统计目录中的文件及子目录个数
class CStatDir:public CBrowseDir
{
protected:
  int m_nFileCount;  //保存文件个数
  int m_nSubdirCount; //保存子目录个数
 
public:
  //缺省构造器
  CStatDir()
  {
    //初始化数据成员m_nFileCount和m_nSubdirCount
    m_nFileCount=m_nSubdirCount=0;
  }
 
  //返回文件个数
  int GetFileCount()
  {
    return m_nFileCount;
  }
 
  //返回子目录个数
  int GetSubdirCount()
  {
    //因为进入初始目录时,也会调用函数ProcessDir,
    //所以减1后才是真正的子目录个数。
    return m_nSubdirCount-1;
  }
 
protected:
  //覆写虚函数ProcessFile,每调用一次,文件个数加1
  virtual bool ProcessFile(const char *filename)
  {
    m_nFileCount++;
    return CBrowseDir::ProcessFile(filename);
  }
 
  //覆写虚函数ProcessDir,每调用一次,子目录个数加1
  virtual void ProcessDir
    (const char *currentdir,const char *parentdir)
  {
    m_nSubdirCount++;
    CBrowseDir::ProcessDir(currentdir,parentdir);
  }
};
 
void main()
{
  //获取目录名
  char buf[256];
  printf("请输入要统计的目录名:");
  gets(buf);
 
  //构造类对象
  CStatDir statdir;
 
  //设置要遍历的目录
  if (!statdir.SetInitDir(buf))
  {
    puts("目录不存在。");
    return;
  }
 
  //开始遍历
 
  vector<string>file_vec = statdir.BeginBrowseFilenames("*.*");
  for(vector<string>::const_iterator it = file_vec.begin(); it < file_vec.end(); ++it)
     std::cout<<*it<<std::endl;
   
  printf("文件总数: %d\n",file_vec.size());
  system("pause");
}

方法四、C++读取某个文件夹下面的子文件夹及其所有文件

下面是输出当前目录下的所有文件夹以及文件的绝对路径(当然也可以是相对路径,由输入的路径决定),下面的函数接口可以改装为单输出文件或者文件夹的接口,这是一个大方面的总接口。

?
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
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
void getAllFiles(string path, vector<string>& files)
{
  //文件句柄
  long  hFile = 0;
  //文件信息
  struct _finddata_t fileinfo; //很少用的文件信息读取结构
  string p; //string类很有意思的一个赋值函数:assign(),有很多重载版本
  if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
  {
    do
    {
      if ((fileinfo.attrib & _A_SUBDIR)) //判断是否为文件夹
      {
        if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
        {
        files.push_back(p.assign(path).append("/").append(fileinfo.name));//保存文件夹名字
          getAllFiles(p.assign(path).append("/").append(fileinfo.name), files);//递归当前文件夹
        }
      }
      else  //文件处理
      {
        files.push_back(p.assign(path).append("/").append(fileinfo.name));//文件名
      }
    } while (_findnext(hFile, &fileinfo) == 0); //寻找下一个,成功返回0,否则-1
    _findclose(hFile);
  }
}
//测试
void main()
{
  string DATA_DIR = "D:/CoderMaker/data_sets/lfw";
  vector<string> files;
  //测试
  char * DistAll = "AllFiles.txt";
  getAllFiles(DATA_DIR, files);//所有文件与文件夹的路径都输出
  ofstream ofn(DistAll); //输出文件流
  int size = files.size();
  int FaiNum = 0;
  ofn << size << endl;
  for (int i = 0; i<size; i++)
  {
    ofn << files[i] << endl;
  }
  ofn.close();
  return 0;
}

测试结果

C++遍历文件夹下所有文件的多种方法

延伸 · 阅读

精彩推荐
  • C/C++关于C语言中E-R图的详解

    关于C语言中E-R图的详解

    今天小编就为大家分享一篇关于关于C语言中E-R图的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    Struggler095962021-07-12
  • C/C++C语言main函数的三种形式实例详解

    C语言main函数的三种形式实例详解

    这篇文章主要介绍了 C语言main函数的三种形式实例详解的相关资料,需要的朋友可以参考下...

    ieearth6912021-05-16
  • C/C++深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下...

    C++教程网5182020-11-30
  • C/C++c/c++内存分配大小实例讲解

    c/c++内存分配大小实例讲解

    在本篇文章里小编给大家整理了一篇关于c/c++内存分配大小实例讲解内容,有需要的朋友们可以跟着学习参考下。...

    jihite5172022-02-22
  • C/C++使用C++制作简单的web服务器(续)

    使用C++制作简单的web服务器(续)

    本文承接上文《使用C++制作简单的web服务器》,把web服务器做的功能稍微强大些,主要增加的功能是从文件中读取网页并返回给客户端,而不是把网页代码...

    C++教程网5492021-02-22
  • C/C++C语言实现双人五子棋游戏

    C语言实现双人五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现双人五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    两片空白7312021-11-12
  • C/C++OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iteye_183805102021-07-29
  • C/C++c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址

    本文给大家汇总介绍了使用c/c++实现获取域名的IP地址的几种方法以及这些方法的核心函数gethostbyname的详细用法,非常的实用,有需要的小伙伴可以参考下...

    C++教程网10262021-03-16