简体   繁体   中英

How to determine if a file is contained by path with Boost Filesystem Library v3?

How can I determine if file is contained by path with boost filesystem v3.

I saw that there is a lesser or greater operator but this seems to be only lexical. The best way I saw was the following:

  • Take the two absolute paths of the file and the path
  • Remove the last part of the file and see if it equals the path (if it does it's contained)

Is there any better way to do this?

The following function should determine whether a file name lies somewhere within the given directory, either as a direct child or in some subdirectory.

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

If you just want to check whether the directory is the immediate parent of the file, then use this instead:

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

You may also be interested in the discussion about what "the same" means with regard to operator== for paths.

If you just want to lexically check if one path is a prefix of another, without worrying about . , .. or symbolic links, you can use this:

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

Note that the four parameter overload of std::mismatch used here wasn't added until C++14.

Of course, if you want more than a strictly lexical comparison of the paths, you can call lexically_normal() or canonical() on either or both parameters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM