为什么boost::filesystem::canonical()要求目标路径存在?
Why does boost::filesystem::canonical() require the target path to exist?
boost::filesystem::canonical(const path& p)
的文档状态:
Overview:将必须存在的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
转换为拟议的N4100std::experimental::filesystem
的过程中(据我所理解),经过适当考虑后是否采用了对canonical()
的限制,或者它只是从Boost定义中"通过"?
我注意到Boost 1.60现在提供了函数weakly_canonical()
: "返回p与符号链接解析和结果标准化。返回:一个路径,它是在p的前导元素(如果存在)和p的不存在元素(如果存在)组成的路径上调用canonical()
函数的结果。"
关于std::filesystem
的更多讨论
尝试weakly_canonical()
它不需要mac上存在的路径
基本上是因为它是realpath的包装器,具有相同的要求。
你可以问realpath
同样的问题,但我认为答案是,如果你试图找出真正的,物理文件或目录的路径名所指,那么如果它是一个破碎的符号链接,那么没有答案,它不指的是一个真正的文件或目录,所以你想要一个错误。
OP的评论下面质疑我的说法,即filesystem::canonical
和realpath
实现相同的操作,但在N4100和POSIX的定义对我来说似乎几乎相同,比较:
realpath()
函数应该从file_name
所指向的路径名派生出一个解析到同一目录项的绝对路径名,该解析不涉及'.'
、'..'
或符号链接。
:
将必须存在的
p
转换为不包含符号链接、"."
和".."
元素的绝对路径。
在这两种情况下,需求是:
-
no symbolic links,如果返回的路径中最后一个组件是符号链接,则不满足要求。
-
规范路径指的是存在的东西,这在N4100中是明确的,在POSIX中是隐含的,因为它指向一些目录条目(即存在的东西),并且目录条目不是符号链接(因为第一个要求)。
关于为什么这些应该是要求,N4100中的注释很有帮助:
[注意:规范路径名允许对路径进行安全检查(例如,此路径是否存在于
/home/goodguy
或/home/badguy
中?) -end Note ]
正如我上面已经说过的,如果它成功返回,即使路径是一个符号链接,实际上没有指向任何东西,那么你需要做额外的工作来检查它是否解析到一个真正的文件,使预期的用例不太方便。
即使有,难道没有理由创建一个没有这个限制的函数的变体吗?(如果没有这样的变体,获取路径需要手动复制canonical()已经完成的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);
}
- C++A*算法并不总是在路径中具有目标节点
- CMake 错误 - 目标 foo INTERFACE_SOURCES属性包含在源目录中以前缀为前缀的路径
- 使用 Libssh 将文件从服务器复制到客户端:分配文件复制目标路径时出现问题
- 生成文件缺少包含路径 尽管路径存在并已定义
- 在迷宫c++中查找路径是否存在
- openCV 库调用不存在的本地路径
- 如何从文件中存在的路径中检索环境变量
- 在QT中的大型项目中指定构建/目标/安装路径
- 有没有一种方法可以使用弗洛伊德-沃歇尔算法给出最短路径,其中存在负权重循环而不允许重叠边缘?
- CMake 安装具有相对路径的目标
- 如果路径的每个元素不存在,请为其创建一个目录
- 检查提升属性树中是否存在路径
- C++'Undefined reference to'错误,尽管包含路径中的头文件中存在函数定义
- 错误53:找不到文件,而是路径中存在所有DLL
- 获取交汇点的目标路径似乎总是以"Error 5 Access Denied"结尾
- 当目标路径存在时,curl SFTP 重命名
- 使用qmake将dll安装到2个目标(路径)中
- 为什么在c++中用shell链接查找快捷方式的目标路径时,它指的是windowsinstaller文件夹
- 为什么boost::filesystem::canonical()要求目标路径存在?
- Qt拖放到windows资源管理器:我如何知道拖放的目标路径