【问题标题】:How do I ignore hidden files (and files in hidden directories) with Boost Filesystem?如何使用 Boost Filesystem 忽略隐藏文件(和隐藏目录中的文件)?
【发布时间】:2012-09-25 23:35:41
【问题描述】:

我正在使用以下内容递归地遍历目录中的所有文件:

try
{
    for ( bf::recursive_directory_iterator end, dir("./");
          dir != end; ++dir )
    {
       const bf::path &p = dir->path();
       if(bf::is_regular_file(p))
       {
           std::cout << "File found: " << p.string() << std::endl;
       }
    }
} catch (const bf::filesystem_error& ex) {
    std::cerr << ex.what() << '\n';
}

但这包括隐藏文件和隐藏目录中的文件。

如何过滤掉这些文件?如果需要,我可以将自己限制在隐藏文件和目录以“。”开头的平台上。字符。

【问题讨论】:

  • 这适用于隐藏文件,但是排除所有存在于隐藏子目录(例如“.svn”)中的非隐藏文件呢?我想我需要检查路径的每个组件是否有初始“。”或类似的东西(也正确处理“../”组件等)。如果 Boost 中存在跨平台的东西,我宁愿使用它,尽管我无法在文档中找到它。
  • 你对“隐藏文件”的定义是什么?
  • @Code-Guru 好问题!如果有一个很好的跨平台定义,我会使用它,只要它在类 Unix 平台上做正确的事情(以“.”开头的文件/目录被隐藏)。也许没有什么好的方法可以抽象出各种隐藏的概念。 Wikipedia 对常见平台上“隐藏”的含义进行了合理的描述。目前我只关心类 Unix 平台,但我喜欢尽可能跨平台。
  • @Soverman: (.svn:) 如果一切都隐藏在那里,你为什么要遍历它? ://
  • @KarolyHorvath 只是因为我还没想出如何用 dir.no_push() 跳过它!

标签: c++ boost boost-filesystem hidden-files


【解决方案1】:

不幸的是,似乎没有一种跨平台的方式来处理“隐藏”。以下适用于类 Unix 平台:

先定义:

bool isHidden(const bf::path &p)
{
    bf::path::string_type name = p.filename();
    if(name != ".." &&
       name != "."  &&
       name[0] == '.')
    {
       return true;
    }

    return false;
}

那么遍历文件就变成了:

try
{
    for ( bf::recursive_directory_iterator end, dir("./");
           dir != end; ++dir)
    {
       const bf::path &p = dir->path();

       //Hidden directory, don't recurse into it
       if(bf::is_directory(p) && isHidden(p))
       {
           dir.no_push();
           continue;
       }

       if(bf::is_regular_file(p) && !isHidden(p))
       {
           std::cout << "File found: " << p.string() << std::endl;
       }
    }
} catch (const bf::filesystem_error& ex) {
    std::cerr << ex.what() << '\n';
}

【讨论】:

  • 既然您有一个可行的答案,您可能需要对其进行优化。在我看来,您通过访问“隐藏”目录中的文件做了很多额外的工作。如果您能找到访问该目录中的文件的方法,则无需检查每个文件的完整路径。
  • if(name != ".." && name != "." && name[0] == '.')。如果 name.empty() == true 怎么办?我建议 if(name != ".." && name != "." && name.length() > 1 && name[0] == '.')
  • @kwirz 我从来没有遇到过允许使用空字符串来命名目录或文件的文件系统。你见过这个吗?
【解决方案2】:

我们现在假设您要忽略以'.' 开头的文件。这是 Unix 中隐藏文件的标准指示。我建议编写一个递归函数来访问每个文件。在伪代码中,它看起来像这样:

visitDirectory dir
    for each file in dir
        if the filename of file does not begin with a '.'
            if file is a directory
                visitDirectory file
            else
                do something with file (perhas as a separate function call?)

这避免了搜索文件的整个路径以确定我们是否要处理它的需要。相反,我们只是跳过任何“隐藏”的目录。

如果您愿意,我也可以考虑几个迭代解决方案。一种是有一个堆栈或队列来跟踪接下来要访问的目录。基本上,这使用您自己的数据结构模拟递归版本。或者,如果您无法解析文件的完整路径,只需确保获得绝对路径即可。这将保证您不会遇到名称为“./”或“../”的目录,这会导致检查隐藏文件时出现问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 2021-07-08
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    相关资源
    最近更新 更多