How do I quot;normalizequot; a pathname using boost::filesystem?(我如何“规范化?使用 boost::filesystem 的路径名?)
问题描述
我们在应用程序中使用 boost::filesystem.我有一个完整"路径,它是通过将多个路径连接在一起而构建的:
We are using boost::filesystem in our application. I have a 'full' path that is constructed by concatenating several paths together:
#include <boost/filesystem/operations.hpp>
#include <iostream>
namespace bf = boost::filesystem;
int main()
{
bf::path root("c:\some\deep\application\folder");
bf::path subdir("..\configuration\instance");
bf::path cfgfile("..\instance\myfile.cfg");
bf::path final ( root / subdir / cfgfile);
cout << final.file_string();
}
最终路径打印为:
c:somedeepapplicationfolder..configurationinstance..instancemyfile.cfg
这是一个有效的路径,但是当我向用户显示它时,我希望它被规范化.(注意:我什至不确定规范化"是否是正确的词为了这).像这样:
This is a valid path, but when I display it to the user I'd prefer it to be normalized. (Note: I'm not even sure if "normalized" is the correct word for this). Like this:
c:somedeepapplicationconfigurationinstancemyfile.cfg
早期版本的 Boost 有一个 normalize()
函数 - 但它似乎已被弃用和删除(没有任何解释).
Earlier versions of Boost had a normalize()
function - but it seems to have been deprecated and removed (without any explanation).
我是否有理由不使用 BOOST_FILESYSTEM_NO_DEPRECATED
宏?有没有其他方法可以使用 Boost 文件系统库来做到这一点?还是应该写代码直接把路径作为字符串操作?
Is there a reason I should not use the BOOST_FILESYSTEM_NO_DEPRECATED
macro? Is there an alternative way to do this with the Boost Filesystem library? Or should I write code to directly manipulating the path as a string?
推荐答案
Boost v1.48 及以上
你可以使用 boost::filesystem::canonical
:
path canonical(const path& p, const path& base = current_path());
path canonical(const path& p, system::error_code& ec);
path canonical(const path& p, const path& base, system::error_code& ec);
http://www.boost.org/doc/libs/1_48_0/libs/filesystem/v3/doc/reference.html#canonical
v1.48 及以上版本还提供了用于解析符号链接的 boost::filesystem::read_symlink
函数.
v1.48 and above also provide the boost::filesystem::read_symlink
function for resolving symbolic links.
正如其他答案中提到的,您无法标准化,因为 boost::filesystem 无法遵循符号链接.但是,您可以编写一个尽可能多地"规范化的函数(假设."和.."被正常处理),因为 boost 提供了确定文件是否为符号链接的能力.
As mentioned in other answers, you can't normalise because boost::filesystem can't follow symbolic links. However, you can write a function that normalises "as much as possible" (assuming "." and ".." are treated normally) because boost offers the ability to determine whether or not a file is a symbolic link.
也就是说,如果.."的父级是一个符号链接,那么你必须保留它,否则删除它可能是安全的,而删除."可能总是安全的.
That is to say, if the parent of the ".." is a symbolic link then you have to retain it, otherwise it is probably safe to drop it and it's probably always safe to remove ".".
它类似于操作实际的字符串,但稍微优雅一些.
It's similar to manipulating the actual string, but slightly more elegant.
boost::filesystem::path resolve(
const boost::filesystem::path& p,
const boost::filesystem::path& base = boost::filesystem::current_path())
{
boost::filesystem::path abs_p = boost::filesystem::absolute(p,base);
boost::filesystem::path result;
for(boost::filesystem::path::iterator it=abs_p.begin();
it!=abs_p.end();
++it)
{
if(*it == "..")
{
// /a/b/.. is not necessarily /a if b is a symbolic link
if(boost::filesystem::is_symlink(result) )
result /= *it;
// /a/b/../.. is not /a/b/.. under most circumstances
// We can end up with ..s in our result because of symbolic links
else if(result.filename() == "..")
result /= *it;
// Otherwise it should be safe to resolve the parent
else
result = result.parent_path();
}
else if(*it == ".")
{
// Ignore
}
else
{
// Just cat other path entries
result /= *it;
}
}
return result;
}
这篇关于我如何“规范化"?使用 boost::filesystem 的路径名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:我如何“规范化"?使用 boost::filesystem 的路径名?
基础教程推荐
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 从 std::cin 读取密码 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01