Jer*_*emy 13 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,symlinks已解析,结果归一化.返回:一个路径,由在canonical()p的前导元素组成的路径上调用函数的结果组成,如果有,则按照由p的元素,如果有的话,不存在."
编辑3:
这更多的讨论有关std::filesystem.
基本上因为它是具有相同要求的realpath的包装器.
您可以问同样的问题realpath,但我认为答案是,如果您试图找出路径名所指的真实的物理文件或目录,那么如果它是一个破损的符号链接,则没有答案,它不是指真实的文件或目录,所以你想要一个错误.
下面的OP评论质疑我的说法filesystem::canonical并realpath执行相同的操作,但N4100和POSIX中的定义看起来几乎与我相同,比较:
该
realpath()功能将派生,从路径指向file_name,绝对路径解析到同一个目录项,其分辨率不涉及'.','..'或符号链接.
和:
p必须存在的转换为没有符号链接"."或".."元素的绝对路径.
在这两种情况下,要求是:
没有符号链接,如果它返回了一个路径,其中最后一个组件是符号链接,不符合要求.
规范路径指的是存在的东西,这在N4100中是显式的,并且在POSIX中隐含,因为它指向某个目录条目(即存在的东西)并且目录条目不是符号链接(因为第一个要求).
至于为什么那些应该是要求,N4100中的注释是有帮助的:
[ 注:规范路径名允许路径的安全检查(如没有此路径住在
/home/goodguy或/home/badguy?)末端注 ]
正如我上面已经说过的,如果它成功返回,即使路径是一个实际上没有指向任何东西的符号链接,那么你需要做额外的工作来检查它是否解析为真实文件,制作预期的用例不太方便.
即使存在,是否也没有理由创建没有此限制的函数变体?(没有这样的变体,获得路径需要容易出错的手动复制99%的规范()已经做了.)
可以说这个变体不太常用,所以不应该是默认的,但如果你需要它,那么就不难做到:
// like canonical() but allows the last component of p to be a broken symlink
filesystem::path
resolve_most_symlinks(filesystem::path const& p, filesystem::path const& base = filesystem::current_path())
{
if (is_symlink(p) && !exists(p))
return canonical(absolute(p, base).remove_filename()) / p.filename();
return canonical(p);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7418 次 |
| 最近记录: |