如何确定文件是否包含在Boost Filesystem Library v3的路径中?

Dav*_*rle 11 c++ boost boost-filesystem

如何确定文件是否包含在boost文件系统v3的路径中.

我看到有一个更小或更大的运算符,但这似乎只是词汇.我看到的最好的方法如下:

  • 获取文件和路径的两个绝对路径
  • 删除文件的最后一部分,看它是否等于路径(如果它包含它)

有没有更好的方法来做到这一点?

Rob*_*edy 16

以下函数应确定文件名是位于给定目录中的某个位置,可以是直接子节点还是某个子目录.

bool path_contains_file(path dir, path file)
{
  // If dir ends with "/" and isn't the root directory, then the final
  // component returned by iterators will include "." and will interfere
  // with the std::equal check below, so we strip it before proceeding.
  if (dir.filename() == ".")
    dir.remove_filename();
  // We're also not interested in the file's name.
  assert(file.has_filename());
  file.remove_filename();

  // If dir has more components than file, then file can't possibly
  // reside in dir.
  auto dir_len = std::distance(dir.begin(), dir.end());
  auto file_len = std::distance(file.begin(), file.end());
  if (dir_len > file_len)
    return false;

  // This stops checking when it reaches dir.end(), so it's OK if file
  // has more directory components afterward. They won't be checked.
  return std::equal(dir.begin(), dir.end(), file.begin());
}
Run Code Online (Sandbox Code Playgroud)

如果您只想检查目录是否是文件的直接父级,那么请改用:

bool path_directly_contains_file(path dir, path file)
{
  if (dir.filename() == ".")
    dir.remove_filename();
  assert(file.has_filename());
  file.remove_filename();

  return dir == file;
}
Run Code Online (Sandbox Code Playgroud)

您还可能有兴趣在什么"相同"是指讨论关于operator==选择路径.

  • 我相信这个函数有一个妨碍安全的缺陷,考虑一下``path_contains_file("folder1/folder2", "folder1/folder2/../../secretFolder/sectedFile.txt")`` 所以如果你用它来进行访问检查,他们可能会错误地通过。使用 ``filesystem::canonical`` 可以解决这个问题,但仅适用于现有文件! (3认同)

Par*_*tes 7

如果您只想在词法上检查一个path是否是另一个的前缀,而不用担心...或符号链接,您可以使用:

bool path_has_prefix(const path & path, const path & prefix)
{
    auto pair = std::mismatch(path.begin(), path.end(), prefix.begin(), prefix.end());
    return pair.second == prefix.end();
}
Run Code Online (Sandbox Code Playgroud)

请注意,std::mismatch这里使用的四个参数重载直到 C++14 才添加。

当然,如果您想要的不仅仅是对路径进行严格的词法比较,您可以对其中一个或两个参数调用lexically_normal()canonical()