为什么boost :: filesystem :: canonical()要求目标路径存在?

时间:2015-07-10 09:54:19

标签: c++ boost boost-filesystem c++17

boost::filesystem::canonical(const path& p)州的文档:

  

概述:将必须存在的p转换为没有符号链接,点或点点元素的绝对路径。
  ...
  备注:!exists(p)是错误。

这样做的结果是,如果p标识其目标不存在的符号链接,则该函数将失败并显示file not found并且不返回路径。

这对我来说似乎过于严格:只是因为链接的目标不存在,我认为没有理由为什么该函数无法解析该不存在的目标的路径。 (相比之下,absolute()没有施加此类限制。)

(显然,如果路径中的符号链接被破坏,则无法解析目标路径。)

那么,这种限制是否有正当理由?

即使存在,是否也没有理由创建没有此限制的函数变体? (没有这样的变体,获取路径需要容易出错的手动复制canonical()已经完成的99%。

我理解stat()lstat()之间存在的语义细微之处同样适用于这种情况 - 这正是我认为函数变体同样合理的原因。

注意:此问题同样适用于std::experimental::filesystem库(n4100),该库基于boost::filesystem

编辑:

在@Jonathan Wakeley下面非常知识渊博的答案之后,我仍然留下了原始问题的精髓,我将稍微重新思考:

  • 是否有潜在的技术或逻辑原因为什么boost::filesystem::canonical()要求目标存在?我的意思是,目标的不存在是否会使得无法解决规范形式的道路?

  • 如果没有,是否有任何技术或逻辑上的理由提出功能的变体,该变体仅与现有表格不同,因为它要求目标存在吗?

  • boost::filesystem对提议的N4100 std::experimental::filesystem的转换(我理解为这种情况)中,canonical()的这一限制是经过适当考虑后采用的,或者它只是从Boost定义中“落空”了吗?

编辑2:

我注意到Boost 1.60现在提供了函数weakly_canonical():“返回p,解析了符号链接并将结果标准化。返回:由组成的路径上调用canonical()函数的结果组成的路径存在的p的主要元素,如果有的话,后面跟着不存在的p元素,如果有的话。“

编辑3:

std::filesystem相关的

More discussion of this

2 个答案:

答案 0 :(得分:8)

尝试weakly_canonical()它不需要mac上存在路径

答案 1 :(得分:6)

基本上因为它是realpath的包装器,它具有相同的要求。

你可以问realpath同样的问题,但我认为答案是如果你试图找出路径名所指的真实的物理文件或目录,那么如果是一个破损的符号链接然后没有答案,它没有引用真实的文件或目录,所以你想要一个错误。

以下OP的评论质疑我filesystem::canonicalrealpath实施相同操作的说法,但N4100和POSIX中的定义与我几乎完全相同,比较:

  

realpath()函数应从file_name指向的路径名派生一个绝对路径名,该路径名解析为同一目录条目,其分辨率不涉及'.',{{1或符号链接。

  

将必须存在的'..'转换为没有符号链接,p"."元素的绝对路径。

在这两种情况下,要求是:

  • 无符号链接,如果它返回的路径中最后一个组件是符号链接,则无法满足要求。

  • 规范路径指的是存在的东西,这在N4100中是显式的,并且在POSIX中隐含,因为它指向某个目录条目(即存在的东西)和目录条目不是符号链接(因为第一个要求)。

至于为什么那些应该是要求,N4100中的注释很有帮助:

  

[注意:规范路径名允许对路径进行安全检查(例如,此路径是否存在".."/home/goodguy?) -end note

正如我上面已经说过的,如果它成功返回,即使路径是没有实际指向任何东西的符号链接,那么你需要做额外的工作来检查它是否能解决到一个真实的文件与否,使预期的用例不太方便。

  

即使存在,是否也没有理由创建没有此限制的函数变体? (如果没有这样的变体,获取路径需要错误的手动复制99%的规范()已经做了。)

可以说这个变体不太常用,所以不应该是默认的,但如果你需要它,那么它不难做到:

/home/badguy