我想从主目录(例如D:\ export \ GeoTIFF)及其子目录中递归搜索属于某个产品类别(例如AIP1)的所有图像产品文件,但是要排除一些搜索中的子文件夹(例如,不带“ AIP1”,即必需的产品类别关键字)。
在实际的生产环境中,我有几种产品类别,例如AIP1,AIP2,AIP3,AIP4等。每个产品类别下都有许多产品,并且在最深的目录中始终有大量带时间戳的imge文件。您可能会看到它们是日期目录(请参阅我的以下示例目录列表作为参考)。因此,为了加快在深沉的目录树下的文件搜索,有必要跳过所有不需要的子目录。我在一个名为“ C ++:使用Boost&C ++ 17获取给定目录及其子目录中的所有文件的列表”的网页上搜索(https://thispointer.com/c-get-the-list-of-all-files-in-a-given-directory-and-its-sub-directories-using-boost-c17/)。下面的附加函数“ vector GetProductFiles(const std :: string&sHomePath,const std :: string&sProductGenre,const std :: string&sExt)”已从“ std :: vector getAllFilesInDir(const std :: string&dirPath,const std: :vector dirSkipList = {})”。
调用GetProductFiles(“ D:\ export \ GeoTIFF”,“ AIP1”,“ .tif”)后,它返回了一个空文件列表向量。在执行步骤的过程中,我发现在while循环中,迭代器(iter)首先位于路径D:\ export \ GeoTIFF \ CHN,然后位于路径D:\ export \ GeoTIFF \ CHN \ AIP102, D:\ export \ GeoTIFF \ CHN \ AIP102 \ 20180723,然后将总共9个文件插入文件向量vListOfFiles中;然后在同级子目录D:\ export \ GeoTIFF \ CHN \ AIP102 \ 20180724下,将其下的另外6个文件添加到文件向量vListOfFiles中。 “ iter.disable_recursion_pending();”每次迭代器(iter)遍历D:\ export \ GeoTIFF \ CHN \ AIP301,D:\ export \ GeoTIFF \ CHN \ AIP303和D:\ export \ GeoTIFF \ CHN \ AIP401时,都会执行命令为了尽早跳过不必要的目录迭代。到目前为止,一切都很好。但是,在迭代路径D:\ export \ GeoTIFF \ DISK之后,退出了循环,而没有关闭其子目录。我哪里错了?
当我注释掉“ iter.disable_recursion_pending();”时命令行,迭代器(iter)可以递归访问D:\ export \ GeoTIFF \ DISK下的子目录。为什么?我尝试更改当前级别,包括使用pop()修饰符,但它不起作用。任何帮助将不胜感激,在此先感谢您!
目录层次结构示例: D:\ export \ GeoTIFF \ CHN \ AIP102 \ 20180723(包括9个文件) D:\ export \ GeoTIFF \ CHN \ AIP102 \ 20180724(包括7个文件) D:\ export \ GeoTIFF \ CHN \ AIP301 \ 20180724 D:\ export \ GeoTIFF \ CHN \ AIP303 \ 20180724 D:\ export \ GeoTIFF \ CHN \ AIP401 \ 20180724
D:\ export \ GeoTIFF \ DISK \ AIP101 \ 20180715 D:\ export \ GeoTIFF \ DISK \ AIP101 \ 20180719 D:\ export \ GeoTIFF \ DISK \ AIP101 \ 20180722 D:\ export \ GeoTIFF \ DISK \ AIP102 \ 20180715 D:\ export \ GeoTIFF \ DISK \ AIP102 \ 20180719 D:\ export \ GeoTIFF \ DISK \ AIP102 \ 20180723 D:\ export \ GeoTIFF \ DISK \ AIP201 \ 20180801 D:\ export \ GeoTIFF \ DISK \ AIP301 \ 20180710
产品图片命名约定: 20180511_000000_AIP02_CHN ____ R1000_LONLAT.tif 20180511_000000_AIP01_DISK ___ R1000_GEOS __。tif
#include <fstream>
#include <iostream>
#include <string>
#include <filesystem>
namespace fs = std::filesystem;
using namespace std;
vector<string> GetProductFiles(const std::string& sHomePath, const std::string& sProductGenre, const std::string& sExt)
{
// Create a vector of string
std::vector<std::string> vListOfFiles;
try
{
// Check if given path exists and points to a directory
if (fs::exists(sHomePath) && fs::is_directory(sHomePath))
{
// Create a Recursive Directory Iterator object and points to the starting of directory
fs::recursive_directory_iterator iter(sHomePath);
// Create a Recursive Directory Iterator object pointing to end.
fs::recursive_directory_iterator end;
// Iterate till end
while (iter != end)
{
// Check if current entry is a directory and mismatch the product category
if (fs::is_directory(iter->path()) &&
iter->path().string().find("AIP") != std::string::npos)
{
if (iter->path().string().find(sProductGenre) == std::string::npos)
{
// C++17 filesystem API to skip current directory iteration
iter.disable_recursion_pending();
}
}
else if (fs::is_regular_file(iter->path()) &&
iter->path().extension().string() == sExt &&
iter->path().string().find(sProductGenre) != std::string::npos)
{
// Add the name in vector
vListOfFiles.push_back(iter->path().string());
}
// Increment the iterator to point to next entry in recursive iteration
error_code ec;
iter.increment(ec);
if (ec) {
std::cerr << "Error While Accessing : " << iter->path().string() << " :: " << ec.message() << '\n';
}
}
}
}
catch (std::system_error & e)
{
std::cerr << "Exception :: " << e.what();
}
return vListOfFiles;
}
int main()
{
std::string sHomePath("D:\\export\\GeoTIFF");
std::string sProdCat("AIP1");
std::string sExt(".tif");
std::vector<std::string> vListOfFiles = GetProductFiles(sHomePath, sProdCat, sExt);
return 0;
}