Windows上的std :: filesystem“ root_name”定义已损坏

时间:2019-02-02 16:10:28

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

我感觉C ++文件系统标准在Windows上被破坏了。它很大程度上基于Boost.filesystem,我在那里发现了一个严重的问题(可能也存在于std :: filesystem:https://github.com/boostorg/filesystem/issues/99

中)

的实质是 “ROOT_NAME” 和 “ROOT_DIRECTORY” 的定义:

  

root-name(可选):标识具有多个根的文件系统上的根(例如“ C:”或“ // myserver”)。如果有歧义,则形成有效根名的最长字符序列被视为根名。除了OS API可以理解的名称外,标准库还可以定义其他根名称。

     

根目录(可选):目录分隔符的是,如果存在的话,马克这个路径作为绝对的。如果丢失(并且根名称以外的第一个元素是文件名),则该路径是相对的,并且需要另一个路径作为起始位置才能解析为文件名。

这需要例如将“ C:\ foo \ bar.txt”分解为:

  • root_name:“ C:”
  • root_directory:“ \”或“ /”(这是否有意义?)
  • 目录:“ foo”
  • 文件名“ bar.txt”

现在的问题:该路径的第一部分是不是一个路径,至少不是原来的一个。这来自Windows上的解释:

  • “ C:\”是驱动器“ C”
  • “ C:”是驱动器“ C”上的当前工作目录

次要:应该如何“\ FOO \跳回到bar.txt”在Windows根据上述解释?你有一个“ROOT_DIRECTORY”(这是奇怪的不是一个目录,而是一个目录的分离器的),但没有“ROOT_NAME”因此,路径不能是绝对的,所以你不要有“ROOT_DIRECTORY”要么。叹气。

因此,据此我感到“ root_name”和“ root_directory”无法分解(在Windows上)。在“C:\富”你就会有“C:\”,并在“C:富”你就会有“C”。或者保持(奇怪的定义)“ROOT_DIRECTORY”你需要一套分解“C:\富”到“C:\”,“\”和“富”而奋斗后者:那是绝对路径?实际上,它是:“文件夹‘富’在驱动器C的当前工作目录”,相当绝对,是不是

但你也可以说“当前工作目录的绝对==独立”,那么“ROOT_DIRECTORY”是有道理的:这将是“\”为“C:\富”,并清空了“C:富”

所以问题:是在定义的标准错误的“C:”作为“ROOT_NAME”而不是“C:\”在像路径“C:\ foo”的或者是它根本无效使用遍历的路径的部件期望前缀总和为“有效”?

2 个答案:

答案 0 :(得分:3)

您对Windows文件系统的解释不正确。目录C:\是“ C”驱动器而不是“ C盘”的根目录。这是从不同的C:,它是在“C”驱动器的当前目录。只需尝试使用Windows Shell,看看C:<stuff>相对于C:\<stuff>的行为。该驱动器上既会获得的东西,但都将这样做在不同的目录开始。

在Windows上用以下术语考虑一下:

  • C:的意思是“转到C驱动器的当前目录”。
  • \在路径开头(在任何根名称之后)表示“转到当前驱动器的根目录”。
  • foo\的意思是“进入我们当前所在的目录中的名为'foo'的目录”。
  • bar.txt的意思是“我们当前所在的目录中名为'bar.txt'的文件。”

因此,C:\foo\bar.txt"的意思是:转到C驱动器的当前目录,然后转到C的根目录,然后转到C的根目录的'foo'目录,然后访问文件C根目录的“ foo”目录中的“ bar.txt”。

类似地,C:foo\bar.txt的意思是:转到C驱动器的当前目录,然后转到C的当前目录的“ foo”目录,然后访问“ foo”中的文件“ bar.txt” 'C当前目录的目录。

这是Windows路径的工作方式。这就是在Windows Shell中键入这些内容的意思。因此,这就是设计Boost / std文件系统路径的方式。

  

但你也可以说“当前工作目录的绝对==独立”

但这不是std文件系统定义the concept of "absolute path"的方式:

  

绝对路径:明确标识文件位置而不引用其他起始位置的路径。路径的该确定它是否绝对是与操作系统相关的。

的元素

因此,“相对”和“绝对”取决于实现。在Windows中,路径不是绝对路径,除非它同时包含根名称和根目录。在Windows文件系统实现,path("\foo\bar.txt").is_absolute()将是错误的。

答案 1 :(得分:1)

您要寻找的是root_path,请参见 Filesystem TS§8.4.9,路径分解

  

path root_path() const;

     

返回:root_name() / root_directory()

Microsoft defines it的方式如下:

  

这两个系统的共同点是,一旦您   超越根名。对于路径名c:/abc/xyz/def.ext

     
      
  • 根名称为c:
  •   
  • 根目录为/
  •   
  • 根路径为c:/
  •   
  • 相对路径为abc/xyz/def.ext
  •   
  • 父路径为c:/abc/xyz
  •   
  • 文件名是def.ext
  •   
  • 茎是def
  •   
  • 扩展名是.ext
  •   

因此,真正的绝对路径将从root_name + root_directoryroot_path开始。

有关解析其他驱动器上的当前目录,另请参见system_complete(p)

  

效果:使用操作系统用来解析作为文件名参数传递给标准库打开函数的路径所用的相同规则,从p组成绝对路径。

     

[示例:对于基于POSIX的操作系统,system_complete(p)具有与absolute(p, current_path()).相同的语义

     

对于基于Windows的操作系统,system_complete(p)的语义与   absolute(p, current_path())(如果p.is_absolute() || !p.has_root_name()p并且   基本具有相同的root_name()。否则,它的行为就像absolute(p, cwd)p.root_name()驱动器的当前目录。这将是上次设置该驱动器的当前目录,因此可能是命令处理器运行的先前程序遗留的残余。尽管这些语义很有用,但可能令人惊讶。 -例子]