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

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

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

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

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

10

Решение

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

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

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

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== для дорожек.

13

Другие решения

Если вы просто хотите лексически проверить, если один 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() по одному или обоим параметрам.

0