c++ boost filesystems boost-filesystem

c++ - boost:: filesystem get relative path



filesystems boost-filesystem (5)

El código de la respuesta aceptada no funciona. Debería ser

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

¿Qué métodos de la biblioteca boost::filesystem pueden ayudarme a obtener una ruta relativa a otra ruta?

Tengo una ruta /home/user1/Downloads/Books y una ruta /home/user1/ . Ahora quiero obtener un camino Downloads/Books .


El código en las respuestas proporcionadas es bastante largo en cada línea. Suponiendo que escribió el namespace fs = boost::filesystem; entonces este código te lleva la mayor parte del camino y me parece más fácil de leer:

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


En las nuevas versiones de boost (comenzando en 1.60), puede usar boost::filesystem::relative . (Consulte la documentación aquí).

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


Tomado de un enlace encontrado al seguir el boleto Nicol vinculado a:

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

Pega eso en un archivo de cabecera y debería hacer lo que quieras.

Ejemplo de llamada:

boost::filesystem::path a("foo/bar"), b("foo/test/korv.txt"); std::cout << make_relative( a, b ).string() << std::endl;


Tristemente, tal función no existe en Boost.Filesystem. Ha sido solicitado , pero parece que no les importa.

Básicamente tienes que hacerlo manualmente.

Boost.Filesystem 1.60 agregó la función relative que se puede usar para manejar esto.