std::filesystem "root_name" 定义在 windows 上被破坏
std::filesystem "root_name" definition broken on windows
我感觉 C++ 文件系统标准在 windows 上被破坏了。它在很大程度上基于 Boost.filesystem,我刚刚在那里发现了一个严重的问题,它(可能)也存在于 std::filesystem 中:https://github.com/boostorg/filesystem/issues/99
本质就是"root_name"和"root_directory"的定义:
root-name(optional): identifies the root on a filesystem with multiple roots (such as "C:" or "//myserver"). In case of ambiguity, the longest sequence of characters that forms a valid root-name is treated as the root-name. The standard library may define additional root-names besides the ones understood by the OS API.
root-directory(optional): a directory separator that, if present, marks this path as absolute. If it is missing (and the first element other than the root name is a file name), then the path is relative and requires another path as the starting location to resolve to a file name.
这需要例如"C:\foo\bar.txt" 分解为:
- root_name: "C:"
- root_directory:“\”或“/”(这有意义吗?)
- 目录:"foo"
- file_name "bar.txt"
现在的问题:这条路径的第一部分不是路径,至少不是原来的路径。这来自对windows的解释:
- "C:\"是驱动器"C"
- "C:" 是驱动器上的当前工作目录 "C"
次要:“\foo\bar.txt”在windows上应该怎么解释?你有一个 "root_directory"(奇怪的是它不是一个目录而是一个目录 分隔符 )但是没有 "root_name" 因此路径不能是绝对的所以你没有"root_directory" 要么。叹息
所以由此我觉得"root_name"和"root_directory"不能分解(在windows上)。在 "C:\foo" 中,您将拥有 "C:\",在 "C:foo" 中,您将拥有 "C:"。或者要保留(奇怪定义的)"root_directory",您需要将 decompose "C:\foo" 设置为 "C:\"、"\" 和 "foo" 并与后者作斗争:Is that an绝对路径?其实是:"The folder 'foo' in the current working directory on drive C",很绝对吧?
但是你可以说 "absolute==independent of current working dir" 那么 "root_directory" 就有意义了:对于 "C:\foo" 它将是“\”,对于 "C:foo".[=15= 则为空]
所以问题:在像 "C:\foo" 这样的路径中将 "C:" 定义为 "root_name" 而不是 "C:\" 的标准是错误的,还是它只是无效的迭代用法期望前缀和为 "valid"?
的路径组件
您对 Windows 文件系统的解释不正确。目录 C:\
是 "C" 驱动器的根目录,而不是 "the drive 'C'"。这与 C:
不同,后者是 "C" 驱动器的当前目录。只需尝试使用 Windows shell 并查看 C:<stuff>
相对于 C:\<stuff>
的表现如何。两者都将访问该驱动器上的内容,但两者都是从不同的目录开始的。
在 Windows 上用这些术语来思考它:
C:
表示 "Go to the current directory of the C drive".
\
在路径的开头(在任何根名称之后)表示 "Go to the root directory of the current drive".
foo\
表示 "Go into the directory called 'foo' within whatever directory we are currently in".
bar.txt
表示 "The file named 'bar.txt' in whatever directory we are currently in."
因此,C:\foo\bar.txt"
的意思是:进入C盘当前目录,然后进入C盘根目录,再进入C盘根目录'foo'目录,然后访问C.
根目录'foo'目录下的文件'bar.txt'
同理,C:foo\bar.txt
表示:进入C盘当前目录,然后进入C盘当前目录'foo'目录,然后访问文件'bar.txt'在C.
当前目录的'foo'目录下
这就是 Windows 路径的工作方式。这就是在 Windows shell 中键入这些内容的意思。因此,这就是 Boost/std 文件系统路径的设计方式。
But well you could say "absolute==independent of current working dir"
但这不是 std 文件系统定义的方式 the concept of "absolute path":
Absolute Path A path that unambiguously identifies the location of a file without reference to an additional starting location. The elements of a path that determine if it is absolute are operating system dependent.
所以 "relative" 和 "absolute" 是依赖于实现的。在 Windows 中,路径不是绝对路径,除非它同时包含 根名称和根目录。在 Windows 文件系统实现中,path("\foo\bar.txt").is_absolute()
将为假。
你要找的是root_path
,见Filesystem TS § 8.4.9,路径分解:
path root_path() const;
Returns: root_name()
/
root_directory()
Microsoft defines it 的做法如下:
Common to both systems is the structure imposed on a pathname once you
get past the root name. For the pathname c:/abc/xyz/def.ext
:
- The root name is
c:
.
- The root directory is
/
.
- The root path is
c:/
.
- The relative path is
abc/xyz/def.ext
.
- The parent path is
c:/abc/xyz
.
- The filename is
def.ext
.
- The stem is
def
.
- The extension is
.ext
.
因此,真正的绝对路径应以 root_name
+ root_directory
或 root_path
.
开头
另请参阅 system_complete(p)
以解析其他驱动器上的当前目录:
Effects: Composes an absolute path from p
, using the same rules used by the operating system to resolve a path passed as the filename argument to standard library open functions.
[Example: For POSIX based operating systems, system_complete(p)
has the same semantics as absolute(p, current_path()).
For Windows based operating systems, system_complete(p)
has the same semantics as
absolute(p, current_path())
if p.is_absolute() || !p.has_root_name()
or p
and
base have the same root_name()
. Otherwise it acts like absolute(p, cwd)
is the current directory for the p.root_name()
drive. This will be the current directory for that drive the last time it was set, and thus may be residue left over from a prior program run by the command processor. Although these semantics are useful, they may be surprising. —end example]
我感觉 C++ 文件系统标准在 windows 上被破坏了。它在很大程度上基于 Boost.filesystem,我刚刚在那里发现了一个严重的问题,它(可能)也存在于 std::filesystem 中:https://github.com/boostorg/filesystem/issues/99
本质就是"root_name"和"root_directory"的定义:
root-name(optional): identifies the root on a filesystem with multiple roots (such as "C:" or "//myserver"). In case of ambiguity, the longest sequence of characters that forms a valid root-name is treated as the root-name. The standard library may define additional root-names besides the ones understood by the OS API.
root-directory(optional): a directory separator that, if present, marks this path as absolute. If it is missing (and the first element other than the root name is a file name), then the path is relative and requires another path as the starting location to resolve to a file name.
这需要例如"C:\foo\bar.txt" 分解为:
- root_name: "C:"
- root_directory:“\”或“/”(这有意义吗?)
- 目录:"foo"
- file_name "bar.txt"
现在的问题:这条路径的第一部分不是路径,至少不是原来的路径。这来自对windows的解释:
- "C:\"是驱动器"C"
- "C:" 是驱动器上的当前工作目录 "C"
次要:“\foo\bar.txt”在windows上应该怎么解释?你有一个 "root_directory"(奇怪的是它不是一个目录而是一个目录 分隔符 )但是没有 "root_name" 因此路径不能是绝对的所以你没有"root_directory" 要么。叹息
所以由此我觉得"root_name"和"root_directory"不能分解(在windows上)。在 "C:\foo" 中,您将拥有 "C:\",在 "C:foo" 中,您将拥有 "C:"。或者要保留(奇怪定义的)"root_directory",您需要将 decompose "C:\foo" 设置为 "C:\"、"\" 和 "foo" 并与后者作斗争:Is that an绝对路径?其实是:"The folder 'foo' in the current working directory on drive C",很绝对吧?
但是你可以说 "absolute==independent of current working dir" 那么 "root_directory" 就有意义了:对于 "C:\foo" 它将是“\”,对于 "C:foo".[=15= 则为空]
所以问题:在像 "C:\foo" 这样的路径中将 "C:" 定义为 "root_name" 而不是 "C:\" 的标准是错误的,还是它只是无效的迭代用法期望前缀和为 "valid"?
的路径组件您对 Windows 文件系统的解释不正确。目录 C:\
是 "C" 驱动器的根目录,而不是 "the drive 'C'"。这与 C:
不同,后者是 "C" 驱动器的当前目录。只需尝试使用 Windows shell 并查看 C:<stuff>
相对于 C:\<stuff>
的表现如何。两者都将访问该驱动器上的内容,但两者都是从不同的目录开始的。
在 Windows 上用这些术语来思考它:
C:
表示 "Go to the current directory of the C drive".\
在路径的开头(在任何根名称之后)表示 "Go to the root directory of the current drive".foo\
表示 "Go into the directory called 'foo' within whatever directory we are currently in".bar.txt
表示 "The file named 'bar.txt' in whatever directory we are currently in."
因此,C:\foo\bar.txt"
的意思是:进入C盘当前目录,然后进入C盘根目录,再进入C盘根目录'foo'目录,然后访问C.
同理,C:foo\bar.txt
表示:进入C盘当前目录,然后进入C盘当前目录'foo'目录,然后访问文件'bar.txt'在C.
这就是 Windows 路径的工作方式。这就是在 Windows shell 中键入这些内容的意思。因此,这就是 Boost/std 文件系统路径的设计方式。
But well you could say "absolute==independent of current working dir"
但这不是 std 文件系统定义的方式 the concept of "absolute path":
Absolute Path A path that unambiguously identifies the location of a file without reference to an additional starting location. The elements of a path that determine if it is absolute are operating system dependent.
所以 "relative" 和 "absolute" 是依赖于实现的。在 Windows 中,路径不是绝对路径,除非它同时包含 根名称和根目录。在 Windows 文件系统实现中,path("\foo\bar.txt").is_absolute()
将为假。
你要找的是root_path
,见Filesystem TS § 8.4.9,路径分解:
path root_path() const;
Returns:
root_name()
/
root_directory()
Microsoft defines it 的做法如下:
Common to both systems is the structure imposed on a pathname once you get past the root name. For the pathname
c:/abc/xyz/def.ext
:
- The root name is
c:
.- The root directory is
/
.- The root path is
c:/
.- The relative path is
abc/xyz/def.ext
.- The parent path is
c:/abc/xyz
.- The filename is
def.ext
.- The stem is
def
.- The extension is
.ext
.
因此,真正的绝对路径应以 root_name
+ root_directory
或 root_path
.
另请参阅 system_complete(p)
以解析其他驱动器上的当前目录:
Effects: Composes an absolute path from
p
, using the same rules used by the operating system to resolve a path passed as the filename argument to standard library open functions.[Example: For POSIX based operating systems,
system_complete(p)
has the same semantics asabsolute(p, current_path()).
For Windows based operating systems,
system_complete(p)
has the same semantics asabsolute(p, current_path())
ifp.is_absolute() || !p.has_root_name()
orp
and base have the sameroot_name()
. Otherwise it acts likeabsolute(p, cwd)
is the current directory for thep.root_name()
drive. This will be the current directory for that drive the last time it was set, and thus may be residue left over from a prior program run by the command processor. Although these semantics are useful, they may be surprising. —end example]