boost::filesystem
库的哪些方法可以帮助我获取相对于另一个路径的路径?boost :: filesystem获取相对路径
我有一个路径/home/user1/Downloads/Books
和路径/home/user1/
。现在我想要一条路径Downloads/Books
。
boost::filesystem
库的哪些方法可以帮助我获取相对于另一个路径的路径?boost :: filesystem获取相对路径
我有一个路径/home/user1/Downloads/Books
和路径/home/user1/
。现在我想要一条路径Downloads/Books
。
从链接摘自以下尼科尔挂票发现:
template < >
path& path::append< typename path::iterator >(typename path::iterator begin, typename path::iterator end, const codecvt_type& cvt)
{
for(; begin != end ; ++begin)
*this /= *begin;
return *this;
}
// Return path when appended to a_From will resolve to same as a_To
boost::filesystem::path make_relative(boost::filesystem::path a_From, boost::filesystem::path a_To)
{
a_From = boost::filesystem::absolute(a_From); a_To = boost::filesystem::absolute(a_To);
boost::filesystem::path ret;
boost::filesystem::path::const_iterator itrFrom(a_From.begin()), itrTo(a_To.begin());
// Find common base
for(boost::filesystem::path::const_iterator toEnd(a_To.end()), fromEnd(a_From.end()) ; itrFrom != fromEnd && itrTo != toEnd && *itrFrom == *itrTo; ++itrFrom, ++itrTo);
// Navigate backwards in directory to reach previously found base
for(boost::filesystem::path::const_iterator fromEnd(a_From.end()); itrFrom != fromEnd; ++itrFrom)
{
if((*itrFrom) != ".")
ret /= "..";
}
// Now navigate down the directory branch
ret.append(itrTo, a_To.end());
return ret;
}
棒,在一个头文件,它应该做你想做的。
样品电话:
boost::filesystem::path a("foo/bar"), b("foo/test/korv.txt");
std::cout << make_relative(a, b).string() << std::endl;
在该示例调用中不需要限定'make_relative'。它可能是错误的(给定的代码看起来不像'make_relative'在'boost :: filesystem'中),如果它是正确的,由于ADL,它是没有必要的。 – MSalters 2013-08-26 11:22:49
不幸的是,Boost.Filesystem中不存在这样的函数。
It has been requested,但他们似乎并不在乎。
你基本上必须手动完成。
Boost.Filesystem 1.60增加了the relative
function可以用来处理这个。
实际上,该补丁被拒绝的原因(使用附加)。 – 2012-04-16 00:55:22
@ MahmoudAl-Qudsi:我链接到一个功能请求。在该请求的评论中有一个补丁链接,但它不是请求的*部分*。 – 2012-04-16 01:09:56
你说得对。也许还有更多的评论会有帮助? :) – 2012-04-16 01:49:12
接受的答案的代码不起作用。它应该是
namespace boost { namespace filesystem {
template <> path& path::append<path::iterator>(path::iterator begin, path::iterator end, const codecvt_type& cvt)
{
for(; begin != end ; ++begin)
*this /= *begin;
return *this;
}
// Return path when appended to a_From will resolve to same as a_To
boost::filesystem::path make_relative(boost::filesystem::path a_From, boost::filesystem::path a_To)
{
a_From = boost::filesystem::absolute(a_From); a_To = boost::filesystem::absolute(a_To);
boost::filesystem::path ret;
boost::filesystem::path::const_iterator itrFrom(a_From.begin()), itrTo(a_To.begin());
// Find common base
for(boost::filesystem::path::const_iterator toEnd(a_To.end()), fromEnd(a_From.end()) ; itrFrom != fromEnd && itrTo != toEnd && *itrFrom == *itrTo; ++itrFrom, ++itrTo);
// Navigate backwards in directory to reach previously found base
for(boost::filesystem::path::const_iterator fromEnd(a_From.end()); itrFrom != fromEnd; ++itrFrom)
{
if((*itrFrom) != ".")
ret /= "..";
}
// Now navigate down the directory branch
ret.append(itrTo, a_To.end());
return ret;
}
} } // namespace boost::filesystem
的代码所提供的答案是相当长的,每行。假设你写namespace fs = boost::filesystem;
那么这段代码可以让你最的方式,看起来更容易读给我听:
static fs::path relativeTo(fs::path from, fs::path to)
{
// Start at the root path and while they are the same then do nothing then when they first
// diverge take the entire from path, swap it with '..' segments, and then append the remainder of the to path.
fs::path::const_iterator fromIter = from.begin();
fs::path::const_iterator toIter = to.begin();
// Loop through both while they are the same to find nearest common directory
while (fromIter != from.end() && toIter != to.end() && (*toIter) == (*fromIter))
{
++toIter;
++fromIter;
}
// Replace from path segments with '..' (from => nearest common directory)
fs::path finalPath;
while (fromIter != from.end())
{
finalPath /= "..";
++fromIter;
}
// Append the remainder of the to path (nearest common directory => to)
while (toIter != to.end())
{
finalPath /= *toIter;
++toIter;
}
return finalPath;
}
这工作对我来说 – 2015-10-09 14:33:05
这看起来比其他答案好多了。 – 2015-12-26 18:52:31
在boost
新版本(在1.60开始),就可以使用boost::filesystem::relative
。 (See the documentation here.)
#include <boost/filesystem.hpp>
#include <iostream>
namespace fs = boost::filesystem;
int main()
{
fs::path parentPath("/home/user1/");
fs::path childPath("/home/user1/Downloads/Books");
fs::path relativePath = fs::relative(childPath, parentPath);
std::cout << relativePath << std::endl;
}
所有其他都失败,将两者都转换为绝对字符串和子字符串。 – 2012-04-16 00:33:25
新版本的boost有一个非常简单的**答案,提供[下面](https://stackoverflow.com/a/37715252/16287) – 2017-10-12 22:11:33