I'm trying to compare two directories and find what files are different inside. So I'm using a boost::filesystem::recursive_directory_iterator
to add all contents of each directory to respective vectors. Then I sort each vector alphabetically and start comparing paths. The problem is it's including the 'base' path and I don't want that, example:
Version1/Assets/info.txt
Version2/Assets/info.txt
Those paths are comparing different, but I want them to compare the same. To clarify, I'm not even checking the binaries yet, just the path name so far. I'd to compare them like this:
/Assets/info.txt
I've been browsing through the boost documentation for a couple hours and I'm convinced there must be an elegant solution for my problem. I realize I could have solved this a while ago by getting a substring of what I want, but there must be a less ugly way.
The boost::filesystem::recursive_directory_iterator
has a path()
property that you can query. You can then use the following decomposition methods available for boost::filesystem::path
to manually build the path to compare:
path root_path() const;
path root_name() const; // returns 0 or 1 element path
path root_directory() const; // returns 0 or 1 element path
path relative_path() const;
path parent_path() const;
path filename() const; // returns 0 or 1 element path
path stem() const; // returns 0 or 1 element path
path extension() const; // returns 0 or 1 element path
For example you can rollout a version of stripping the root as follows:
#include <iostream>
#include <boost/filesystem.hpp>
boost::filesystem::path strip_root(const boost::filesystem::path& p) {
const boost::filesystem::path& parent_path = p.parent_path();
if (parent_path.empty() || parent_path.string() == "/")
return boost::filesystem::path();
else
return strip_root(parent_path) / p.filename();
}
int main() {
std::cout << strip_root("/a") << std::endl;
std::cout << strip_root("/a/b") << std::endl;
std::cout << strip_root("/a/b/c") << std::endl;
std::cout << strip_root("/a/b.dir/c.ext") << std::endl;
}
// Output:
""
"b"
"b/c"
"b.dir/c.ext"
I think I have cleaner solution:
fs::path stripFirstDir(fs::path p)
{
p = p.relative_path();
if (p.empty()) return {};
return p.lexically_relative(*p.begin());
}
https://godbolt.org/z/hr3hcr
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With