基本思想:帮别人写了一段小代码,在Darknet yolo 实现多张图片的加载和训练,如何遍历多层目录的文件夹,获取其文件目录和目录下的文件;

文件目录结构如下:

ubuntu@ubuntu:/mnt/f/test_root$ tree
.
├── 99_775023100073
│ ├── 99_77_5023100073.xml
│ ├── 99_77_5023100073_difference.jpg
│ ├── 99_77_Capture_20200225023100073_original.jpg
│ └── 99_77_Capture_20200225073100393_original.jpg
├── 99_775073100393
│ ├── 99_77_20200225073100393_difference.jpg
│ ├── 99_77_5073100393.xml
│ ├── 99_77_Capture_20200225073100393_original.jpg
│ └── 99_77_Capture_20200225100126772_original.jpg
├── 99_775100126772
│ ├── 99_77_5100126772.xml
│ ├── 99_77_5100126772_difference.jpg
│ ├── 99_77_Capture_20200225100126772_original.jpg
│ └── 99_77_Capture_20200225120156242_original.jpg
└── 99_775120156242
├── 99_77_5120156242.xml
├── 99_77_5120156242_difference.jpg
├── 99_77_Capture_20200225120156242_original.jpg
└── 99_77_Capture_20200225140100779_original.jpg

4 directories, 16 files

代码版本一:只能支支持window 下的编辑器 Visual Studio  / MinGW /QT 

#include <stdio.h>
#include<iostream>
#include <cstring>
#include <io.h>
#include <vector>
#include <algorithm>

bool fileSearch(std::string inPath,std::vector<std::string> &dirPathName,std::vector<std::string> &filePathName)
{
dirPathName.push_back(inPath);
long handle;
struct _finddata_t fileinfo;
//第一次查找
std::string fullPath=inPath+"\\*.jpg";
handle = _findfirst(fullPath.c_str() ,&fileinfo);
if(handle == -1)
return -1;
do
{
//找到的文件的文件名

// printf("%s %s\n",inPath.c_str(), fileinfo.name);
filePathName.push_back(inPath+"\\"+fileinfo.name);
std::sort(filePathName.begin(),filePathName.end());


} while (!_findnext(handle,&fileinfo));

}

void dirSearch(std::string path,std::vector<std::string> &dirPathName,std::vector<std::string> &filePathName)
{
struct _finddata_t file;
long fileHandle;
std::string curPath = path + "\\*.*";
if ((fileHandle = _findfirst(curPath.c_str(), &file)) == -1)
{
return;
}

do {
if (strcmp(file.name, "..")!=0 && strcmp(file.name, ".")!=0)
{
if (_A_SUBDIR == file.attrib)
{
curPath = path + "\\" + file.name;

//printf("%s\n", curPath.c_str());
fileSearch( curPath ,dirPathName,filePathName);
dirSearch(curPath,dirPathName,filePathName);
}

}
} while (!(_findnext(fileHandle, &file)));
_findclose(fileHandle);
}



int main() {


const char *path = "F:\\test_root";
std::vector<std::string> dirPathName;
std::vector<std::string> filePathName;
dirSearch("F:\\test_root",dirPathName,filePathName); //目录搜索

for(int i=0;i<dirPathName.size();i++)
{
std::cout<<dirPathName[i]<<std::endl;
}

for(int i=0;i<filePathName.size();i++) {
printf("%s\n", filePathName[i].c_str());
}

printf("\n ----------------------\n");
filePathName.clear();
std::vector<std::string>().swap(filePathName);
fileSearch("F:\\test_root\\S0027_z100035_20200225073100393",dirPathName,filePathName); //子目录搜索

for(int i=0;i<filePathName.size();i++) {
printf("%s\n", filePathName[i].c_str());
}
return 0;
}

结果:(注:该代码无法在linux 系统执行,因为没有window 的库 io.h 无法使用 struct _finddata_t fileinfo)

F:\searchDir\cmake-build-debug\searchDir.exe
F:\test_root\99_775023100073
F:\test_root\99_775073100393
F:\test_root\99_775100126772
F:\test_root\99_775120156242
F:\test_root\99_775023100073\99_77_5023100073_difference.jpg
F:\test_root\99_775023100073\99_77_Capture_20200225023100073_original.jpg
F:\test_root\99_775023100073\99_77_Capture_20200225073100393_original.jpg
F:\test_root\99_775073100393\99_77_20200225073100393_difference.jpg
F:\test_root\99_775073100393\99_77_Capture_20200225073100393_original.jpg
F:\test_root\99_775073100393\99_77_Capture_20200225100126772_original.jpg
F:\test_root\99_775100126772\99_77_5100126772_difference.jpg
F:\test_root\99_775100126772\99_77_Capture_20200225100126772_original.jpg
F:\test_root\99_775100126772\99_77_Capture_20200225120156242_original.jpg
F:\test_root\99_775120156242\99_77_5120156242_difference.jpg
F:\test_root\99_775120156242\99_77_Capture_20200225120156242_original.jpg
F:\test_root\99_775120156242\99_77_Capture_20200225140100779_original.jpg

----------------------
F:\test_root\99_775120156242\99_77_5120156242_difference.jpg
F:\test_root\99_775120156242\99_77_Capture_20200225120156242_original.jpg
F:\test_root\99_775120156242\99_77_Capture_20200225140100779_original.jpg

Process finished with exit code 0

版本二:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <iostream>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>

using namespace std;

// 递归列出所有目录及文件
void recursion_scan_dir_file(char *dir, vector<char *> &dirPathName, vector<char *> &filePathName,int depth) {
DIR *p_dir = NULL;
struct dirent *p_entry = NULL;
struct stat statbuf;


if ((p_dir = opendir(dir)) == NULL) {
printf("can't open dir.\n");
return;
}

chdir(dir);

while (NULL != (p_entry = readdir(p_dir))) { // 获取下一级目录信息

lstat(p_entry->d_name, &statbuf); // 获取下一级成员属性

if (S_IFDIR & statbuf.st_mode) { // 判断下一级成员是否是目录
if (strcmp(".", p_entry->d_name) == 0 || strcmp("..", p_entry->d_name) == 0)
continue;

//printf("%*s%s/\n", depth, "", p_entry->d_name);

char *dirf =(char*)malloc(sizeof(char)*10000);
sprintf(dirf, "%s/%s",dir, p_entry->d_name);
dirPathName.push_back(dirf);
recursion_scan_dir_file(p_entry->d_name,dirPathName, filePathName, depth + 4); // 扫描下一级目录的内容
} else {
// printf("%*s%s\n", depth, "", p_entry->d_name); // 输出属性不是目录的成员
char *fullpath =(char*)malloc(sizeof(char)*1000);
if(dirPathName.size()) {
sprintf(fullpath, "%s/%s", dirPathName[dirPathName.size() - 1], p_entry->d_name);
//printf(" %s\n", fullpath); // 输出属性不是目录的成员
filePathName.push_back(fullpath);
}else{
sprintf(fullpath, "%s/%s", dir, p_entry->d_name);
//printf(" %s\n", fullpath); // 输出属性不是目录的成员
filePathName.push_back(fullpath);
}
}
}
chdir(".."); // 回到上级目录
closedir(p_dir);
}

//列出一个目录下所有文件
void scan_one_dir(const char *dir_name) {
if (NULL == dir_name) {
cout << " dir_name is null ! " << endl;
return;
}

struct stat s;
lstat(dir_name, &s);
if (!S_ISDIR(s.st_mode)) {
return;
}

struct dirent *filename;
DIR *dir;
dir = opendir(dir_name);
if (NULL == dir) {
return;
}

int iName = 0;
while ((filename = readdir(dir)) != NULL) {
if (strcmp(filename->d_name, ".") == 0 ||
strcmp(filename->d_name, "..") == 0)
continue;

char wholePath[128] = {0};
sprintf(wholePath, "%s/%s", dir_name, filename->d_name);

cout << "wholePath= " << wholePath << endl;
}
}


int main(int argc, char *argv[]) {
char *basePath = "/mnt/f/test_root/99_775023100073/";


vector<char *> dirPathName, filePathName;
scan_one_dir( basePath);
recursion_scan_dir_file(basePath ,dirPathName, filePathName, 1);

for (int i = 0; i < filePathName.size(); i++) {
printf(" %s\n", filePathName[i]);
free(filePathName[i]);
}
filePathName.clear();
vector<char*>().swap(filePathName);

return 0;
}

结果:(注 只能在linux上运行)

ubuntu@ubuntu:/mnt/f/searchDir$ ./a.out
wholePath= /mnt/f/test_root/99_775023100073//99_77_5023100073.xml
wholePath= /mnt/f/test_root/99_775023100073//99_77_5023100073_difference.jpg
wholePath= /mnt/f/test_root/99_775023100073//99_77_Capture_20200225023100073_original.jpg
wholePath= /mnt/f/test_root/99_775023100073//99_77_Capture_20200225073100393_original.jpg
/mnt/f/test_root/99_775023100073//99_77_5023100073.xml
/mnt/f/test_root/99_775023100073//99_77_5023100073_difference.jpg
/mnt/f/test_root/99_775023100073//99_77_Capture_20200225023100073_original.jpg
/mnt/f/test_root/99_775023100073//99_77_Capture_20200225073100393_original.jpg