Как определить, содержится ли файл по пути с помощью Boost Filesystem Library v3?

Как определить, содержит ли файл путь с файловой системой boost v3.

Я видел, что есть меньший или больший оператор, но это кажется лексическим. Лучший способ, который я видел, это следующее:

  • Возьмите два абсолютных пути файла и путь
  • Удалите последнюю часть файла и посмотрите, равен ли он пути (если он содержит)

Есть ли лучший способ сделать это?

Ответ 1

Следующая функция должна определять, находится ли имя файла где-то внутри данного каталога, либо как прямой, либо в каком-либо подкаталоге.

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 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 OK if file
  // has more directory components afterward. They won't be checked.
  return std::equal(dir.begin(), dir.end(), file.begin());
}

Если вы просто хотите проверить, является ли каталог непосредственным родителем файла, используйте вместо этого:

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;
}

Вас также может заинтересовать обсуждение того, что означает "то же самое" в отношении operator== для путей.

Ответ 2

Если вы просто хотите лексически проверить, является ли один 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();
}

Конечно, если вы хотите больше, чем строго лексическое сравнение путей, вы можете вызвать lexically_normal() или canonical() для одного или обоих параметров.