当前位置:   article > 正文

c++ 遍历文件夹_c++遍历文件夹

c++遍历文件夹

主要使用两个函数<io.h>中的_findfirst()  ,_findnext

使用<io.h>中的_findfirst()  ,_findnext 进行文件查找时,句柄类型可能为int64,而不一定是long;

具体的类型有运行环境决定,推荐使用auto类型自动推导合适的类型,再需要时可以用<typeinfo>下的typeid(变量名).name() 得到实际推导出的类型名字;

  1. #pragma once
  2. #include<io.h>
  3. #include<iostream>
  4. #include<string>
  5. #include<vector>
  6. using namespace std;
  7. class GetT
  8. {
  9. private:
  10. string path = "*.*";//文件路径。 ps::此为文件名格式,*作为通配符代表所有文件名或文件后缀,可以按需求指定查找确定的文件名或后缀名
  11. _finddata_t fileInfo; //存储找到文件时返回的该文件的信息
  12. public:
  13. void main(string args = "");
  14. void getCurrent(string path = "未输入路径", vector<string> fileDir = {} );//默认参数方便重载调用
  15. };
  16. /// <summary>
  17. /// 主方法
  18. /// </summary>
  19. /// <param name="args"></param>
  20. void GetT::main(string args)
  21. {
  22. getCurrent(path);
  23. }
  24. /// <summary>
  25. /// 通过一个路径(目录)开始查找所有文件(包括文件夹)
  26. /// 按广度优先算法对子文件夹进行同样的查找操作;
  27. /// </summary>
  28. /// <param name="path">要查找的目录</param>
  29. /// <param name="fileDir">查找到结果中其他目录的集合</param>
  30. /// 注意:查找的第一个文件是 “.”,代表当前目录,第二个文件是“..”代表上一级目录;
  31. inline void GetT::getCurrent(string path , vector<string> fileDir)//用来缓存文件夹目录
  32. {
  33. if (path == "未输入路径") path = this->path;
  34. int index = 0;
  35. //TODO::找到第一个文件(即当前目录) ? 继续 :结束
  36. auto handle = _findfirst(path.c_str(), &fileInfo);//_findfirst() 没找到文件时,返回-1,找到了就返回句柄
  37. if (handle == -1) return;
  38. else
  39. {
  40. }
  41. //TODO::找到第二个文件(即上一级目录) ? 继续 :结束
  42. if (0 == _findnext(handle, &fileInfo)) //_findnext() 找到文件时返回0,没找到文件时返回-1
  43. {
  44. }
  45. else return;
  46. //TODO::查找后续的其他文件(即实际显示在资源管理器里的文件或文件夹)
  47. while (1)
  48. {
  49. //没找到下一个文件 ?跳出循环 :继续执行
  50. if (-1 == _findnext64i32(handle, &fileInfo)) break;
  51. //TODO::是文件夹? 记录进fileDir :作为文件处理
  52. if (fileInfo.attrib == _A_SUBDIR)
  53. {
  54. fileDir.push_back(path + "/" + fileInfo.name);
  55. }
  56. else
  57. {
  58. //TODO::此处按需要补充对找到的文件的处理
  59. }
  60. }
  61. //TODO::当前文件夹已经查找完毕,开始查找下一层子文件夹
  62. for (auto sub : fileDir)
  63. {
  64. getCurrent(sub);
  65. }
  66. }

补充一个适合复用的版本:

  1. #pragma once
  2. #include <io.h>
  3. #include <iostream>
  4. #include <atlstr.h>
  5. #include <queue>
  6. using namespace std;
  7. //--------------------------------
  8. extern "C" _declspec(dllexport)
  9. char* GetCurrentDir();
  10. typedef bool (*FileStdCall)(const char* _FilePath);//_对文件的回调函数指针类型
  11. typedef bool (*DirStdCall)(const char* _Directory);//_对文件夹的回调函数指针类型
  12. /// <summary>
  13. /// 遍历文件夹和文件
  14. /// </summary>
  15. /// <param name="_BeginPath">其实文件夹</param>
  16. /// <param name="_DirCall">回调函数,处理查找到的文件夹</param>
  17. /// <param name="_FileCall">回调函数,处理查找到的文件</param>
  18. /// <param name="_ifOnlyFirstDeep"></param>
  19. extern "C" _declspec(dllexport)
  20. void ErgodicDirAndFile(char* _BeginPath = NULL,
  21. DirStdCall _DirCall = NULL,
  22. FileStdCall _FileCall = NULL,
  23. bool _ifOnlyFirstDeep = false)
  24. {
  25. _finddata_t FindData;//_查找文件时存储返回的信息
  26. HANDLE handlet; //_句柄
  27. queue<string> DirQueue;//需要查找的目录队列,char*处理起来太麻烦,担心内存泄露,改用了string。
  28. //参数重载
  29. if (_BeginPath == NULL)
  30. {
  31. _BeginPath = GetCurrentDir();
  32. }
  33. //对目录队列写入第一个元素
  34. DirQueue.push(string(_BeginPath));
  35. //遍历队列所有目标
  36. while (1)
  37. {
  38. string path;
  39. //结束遍历 ? 取出一个元素进行遍历
  40. if (DirQueue.empty())
  41. break;
  42. else {
  43. path = DirQueue.front();
  44. DirQueue.pop();
  45. }
  46. //查找开始
  47. {
  48. //路径检错
  49. if (_access(path.c_str(), 0) == -1)
  50. break;
  51. //查找第一个结果(是上级目录)
  52. auto handle = _findfirst( (path+"\\*.*").c_str(), &FindData);
  53. if (handle == -1) return;
  54. //查找第二个结果(是当前目录)
  55. if (-1 == _findnext(handle, &FindData)) {
  56. cout << "Failed == " << FindData.name << endl;
  57. cout << "Failed == " << path << endl;
  58. return;
  59. }
  60. //查找目录下的其他结果
  61. while(1){
  62. //跳出条件
  63. if (-1 == _findnext(handle, &FindData))
  64. break;
  65. switch (FindData.attrib)
  66. {
  67. //对文件夹
  68. case _A_SUBDIR: {
  69. //子文件夹压入等待队列中
  70. DirQueue.push( path + "\\"+string(FindData.name));
  71. if(_DirCall != NULL)
  72. _DirCall(path.c_str());
  73. break;
  74. }
  75. //对只读文件
  76. case _A_RDONLY: {
  77. }
  78. //对其他文件(正常,隐藏,系统,存档)
  79. case _A_NORMAL:
  80. case _A_HIDDEN:
  81. case _A_SYSTEM:
  82. case _A_ARCH:
  83. {
  84. if(_FileCall != NULL)
  85. _FileCall( (path+"\\"+FindData.name).c_str());
  86. break;
  87. }
  88. default:
  89. break;
  90. }
  91. }
  92. }
  93. //是否只查找一层
  94. if (_ifOnlyFirstDeep == true)
  95. break;
  96. }
  97. }
  98. //------------------------------------
  99. /// <summary>
  100. /// 获取当前工作目录名称
  101. /// 备注::多线程时可能不保证运行安全
  102. /// </summary>
  103. /// <returns></returns>
  104. extern "C" _declspec(dllexport)
  105. char* GetCurrentDir()
  106. {
  107. CString path;
  108. static string result;
  109. {
  110. GetModuleFileName(NULL, path.GetBufferSetLength(MAX_PATH + 1), MAX_PATH);
  111. path.ReleaseBuffer();
  112. path = path.Left(path.ReverseFind('\\'));//只取‘\\'左边的部分,(剥离文件名,只留下目录名)
  113. result = string((CW2A)path.GetString());
  114. }
  115. return (char*)result.c_str();
  116. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/716123
推荐阅读
相关标签
  

闽ICP备14008679号