使用 boost::filesystem::path 获取绝对路径

Posted

技术标签:

【中文标题】使用 boost::filesystem::path 获取绝对路径【英文标题】:Get absolute path with boost::filesystem::path 【发布时间】:2012-09-20 13:36:36 【问题描述】:

我当前的工作目录位于/home/myuser/program,我创建了一个指向它的boost::filesystem::path 对象。我附加了/../somedir,所以它变成了/home/myuser/program/../somedir。但我需要得到它的解析绝对路径,即/home/myuser/somedir

我已经尝试了很长时间,我在their reference 中找不到任何方法可以做到这一点。有一个名为make_absolute 的方法,它似乎应该做我所期望的,但我必须给它一个“根”路径参数。应该是哪个?我真的需要这样做才能获得真正的绝对路径吗?有没有其他办法?

【问题讨论】:

【参考方案1】:

make_absolute 有一个 可选 第二个参数的 documentation shows,默认为您当前的路径:

path absolute(const path& p, const path& base=current_path());

不带第二个参数试试看是否返回你要找的结果。

【讨论】:

这是文档中让我有点恼火的不一致之处之一。有一个 make_absolute 方法有一个参数,当我点击链接时,它会将我引导到接受两个参数的 absolute() 函数的文档。尽管如此,像absolute(pathObject).string() 这样的操作将返回相同的未解析路径。这是你的建议,对吧?【参考方案2】:

我必须给它一个“根”路径参数。

Check the docs:你没有给它任何东西;它有一个默认的第二个参数。即当前目录。

相对路径是相对于某个目录的。因此,在制作绝对路径时,您需要知道它应该是绝对的相对于。那就是“根路径”:它相对的目录。

【讨论】:

【参考方案3】:

你说你想要一个绝对路径,但你的例子表明你已经有了一个绝对路径。删除路径的.. 组件的过程称为规范化。为此,您应该致电canonical。它恰好也执行absolute的任务,所以你不需要先调用absolutemake_absolutemake_absolute 函数需要基本路径;如果你没有更好的,你可以通过current_path()

【讨论】:

完全正确。例如,我不想使用“规范”这个词,因为我不确定它是否也意味着已解析的符号链接等。我试过你的建议,它立即奏效。谢谢。 请注意,如果文件不存在,规范会引发异常。所以你可以只构建现有的路径。【参考方案4】:

更新,因为这似乎仍然是谷歌关于绝对路径的热门话题:

从 Boost 1.57 开始,一些之前建议的功能已被删除。

对我有用的解决方案是

boost::filesystem::path canonicalPath = boost::filesystem::canonical(previousPath, relativeTo);

(使用独立方法canonical(),在 boost/filesystem/operations.hpp 中定义,通过 boost/filesystem.hpp 自动包含)

重要提示:在不存在的路径上调用规范(例如,您要创建文件)将引发异常。在这种情况下,您的下一个最佳选择可能是 boost::filesystem::absolute()。它也适用于不存在的 路径,但不会去掉路径中间的点(如 a/b/c/../../d.txt)。 注意:确保 relativeTo 引用一个目录,在引用文件的路径上调用 parent_path()(例如,打开的文件包含相对于自身的目录或文件路径)。

【讨论】:

什么是“previousPath”和“relativeTo”的示例路径字符串?我不太清楚输入在路径样式方面需要是什么样的。 以前的路径可能类似于 path("../../readme.txt"),而 relativeTo = path("c:/example/test/blah") 这应该解析为“ c:/example/readme.txt”。如果先前的路径已经是绝对路径,则不确定 relativeTo 的作用(或者是否甚至需要合理的输入)。【参考方案5】:
// input: d:\\tmp\\\\a/../VsDebugConsole.png
// output: d:\\tmp\\VsDebugConsole.png
static std::wstring fix_path(std::wstring path)

    //boost::replace_all(path, L"\\\\", L"\\");
    //boost::replace_all(path, L"//", L"/");
    boost::filesystem::path bpath(path);
    bpath = boost::filesystem::system_complete(bpath);

    return bpath.wstring();

【讨论】:

你能补充一点解释吗?

以上是关于使用 boost::filesystem::path 获取绝对路径的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)