递归目录文件搜索,跳过无关路径

时间:2018-08-04 16:13:32

标签: filesystems c++17

我想从主目录(例如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;
}

0 个答案:

没有答案