【问题标题】:Get directory separator char on Windows? ('\', '/', etc.)在 Windows 上获取目录分隔符? ('\', '/', ETC。)
【发布时间】:2011-09-06 03:22:56
【问题描述】:

tl;dr:如何询问 Windows 系统上当前的目录分隔符是什么?


不同版本的 Windows 似乎表现不同(例如,\/ 都适用于英文版本,¥ is apparently on the Japanese version, ₩ is apparently on the Korean version 等...

有什么办法可以避免硬编码,而是在运行时询问 Windows?

注意:

理想情况下,解决方案应该依赖于像 ShlWAPI.dll 这样的高级 DLL,因为低级库也依赖于此。所以它应该真的取决于kernel32.dllntdll.dll 或类似的东西......尽管我很难找到任何东西,无论是在高级别还是在低级别。

编辑:

一个小实验告诉我,它是 Win32 子系统(即 kernel32.dll... 还是 ntdll.dll 中的 RtlDosPathNameToNtPathName_U?不确定,没有测试...)将正斜杠转换为反斜杠,而不是内核。 (前缀 \\?\ 使得后面的路径中无法使用正斜杠 - 并且 NT 原生用户模式 ​​API 也会因正斜杠而失败。)

所以显然它不是完全“内置”在 Windows 中,而只是一个兼容性功能——这意味着你不能盲目地用斜杠代替反斜杠,因为任何在路径上随机添加 \\?\ 前缀的程序都会自动中断在正斜杠上。

我对对此做出什么结论感到复杂,但我只是想提一下。

(我将其标记为“路径分隔符”,尽管这在技术上是不正确的,因为路径分隔符用于分隔 路径,而不是目录(;\)。希望人们明白我的意思。)

【问题讨论】:

  • 分隔符是一样的。总是0x5c。不同之处在于用于显示字符的代码页。在 ANSI 代码页中,0x5c 是反斜杠。在日文代码页 932 中,0x5c 是日元符号,而在韩文代码 (949) 页中,它是韩元符号。
  • 我同意 vcsjones,Path handling 的文档提到它是分隔目录的反斜杠 (0x5c)。事实上,如果您将机器切换到日语语言环境,按 \ 键将产生 ¥ 而不是 \。
  • @vcsjones, Joshua:我没有意识到是这种情况,感谢您指出。但是,我仍然需要一种机制来检测/(或其他字符)是否是路径分隔符——在 Windows 7 上似乎是这样,但在 XP 上却不是,我宁愿避免硬编码这条规则如果可能的话。

标签: c winapi path path-separator


【解决方案1】:

虽然¥ 字符在各自的韩文和日文Windows 版本中显示为目录分隔符符号,但它们只是这些版本的Windows 将相同的Unicode 代码点U+005c 表示为字形的方式。反斜杠的底层代码点在英文 Windows 以及日文和韩文 Windows 版本中仍然相同。

可以在此页面上找到对此的额外确认:http://msdn.microsoft.com/en-us/library/dd374047(v=vs.85).aspx

文件名中字符集的安全注意事项

在日语系统上使用的 Windows 代码页和 OEM 字符集包含日元符号 (¥) 而不是反斜杠 (\)。因此,日元字符是 NTFS 和 FAT 文件系统的禁止字符。将 Unicode 映射到日语代码页时,转换函数将反斜杠 (U+005C) 和正常的 Unicode 日元符号 (U+00A5) 映射到同一个字符。出于安全原因,您的应用程序通常不应允许 Unicode 字符串中的字符 U+00A5 可能被转换为 FAT 文件名。

另外,我不知道有任何 Windows API 函数可以为您获取系统的路径分隔符,但在任何情况下您都可以依赖它为 \

http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx#naming_conventions

以下基本规则使应用程序能够创建和处理文件和目录的有效名称,而不管文件系统如何:

...

使用反斜杠 (\) 分隔路径的组成部分。反斜杠将文件名与其路径分开,并将一个目录名与路径中的另一个目录名分开。您不能在实际文件或目录的名称中使用反斜杠,因为它是将名称分隔为组件的保留字符。

...

关于/

Windows 应该将support the use of / 作为 API 函数中的目录分隔符,但不一定在命令提示符中 (command.com)。

注意 Windows API 中的文件 I/O 函数将“/”转换为“\”作为将名称转换为 NT 样式名称的一部分,除非使用“\?\”前缀,如以下部分所述.

要弄清楚这一切的真相是“困难的”,但这可能是 Windows 路径中关于 / 的一个非常有用的链接:http://bytes.com/topic/python/answers/23123-when-did-windows-start-accepting-forward-slash-path-separator

【讨论】:

  • +1 因为我没有意识到货币符号的问题。 但是,我仍然需要一种机制来检测/(或任何其他字符)是否是路径分隔符——它在 Windows 7 上似乎是这样,但在 XP 上却不是,我会尽量避免硬编码这条规则。
  • 我认为您误认为正斜杠在 XP 上不起作用。从 DOS 开始就一直有效。
  • @Mehrdad - 每个 Windows 版本都支持 / 作为目录路径分隔符。 Windows API 将/ 视为路径分隔符的特殊符号,但某些软件可能无法将其识别为路径分隔符(如command.com),因为它已被保留用于其他用途。如果您使用的是 Windows API,它们应该将包含 / 和“\”的路径转换为正确的路径。
  • @birryree:真的吗?我以为我在 XP 的命令提示符(即cmd.exe)上尝试过,但它不喜欢反斜杠……不过会再试一次。
  • 我的意思是当传递给接受路径名的系统 API 函数时(对于 DOS,这意味着 int 21h)。
【解决方案2】:

原发帖者在别人的回答中添加了“kernel-mode”这句话。

如果最初的问题是要询问内核模式,那么依赖 / 作为路径分隔符可能不是一个好主意。不同的文件系统允许在磁盘上使用不同的字符集。 Windows 中不同的文件系统驱动程序也可以允许不同的字符集,这些字符集通常不能包含底层文件系统在磁盘上不接受的字符,但有时它们的行为可能会很奇怪。例如,Posix 模式允许组件名称在 NTFS 分区的路径名称中包含某些字符,即使 NTFS 通常不允许这些字符。 (但显然 / 不是其中之一,在 Posix 中。)

在 Unicode 的内核模式中,U+005C 始终是反斜杠,并且始终是路径分隔符。日元和韩元的 Unicode 代码点不是 U+005C,也不是路径分隔符。

在 ANSI 的内核模式中,复杂性取决于哪个 ANSI 代码页。在与 ASCII 非常相似的代码页中,0x5C 是一个反斜杠,它是路径分隔符。在 ANSI 代码页 932 和 949 中,0x5C 不是反斜杠,但 0x5C 可能是路径分隔符,具体取决于它出现的位置。如果 0x5C 是多字节字符的第一个字节,则它是日元符号或韩元符号,它是路径分隔符。如果 0x5C 是多字节字符的第二个字节,那么它本身就不是字符,所以它不是日元符号或韩元符号,也不是路径分隔符。您必须从字符串的开头开始解析,以确定一个特定的字符是否实际上是一个完整的字符。同样在中文和 UTF-8 中,多字节字符可以长于两个字符。

【讨论】:

    【解决方案3】:

    标准正斜杠 (/) 在所有版本的 DOS 和 Windows 中始终有效。如果您使用它,您不必担心反斜杠在日文和韩文版本的 Windows 上的显示方式问题,并且您也不必为 Windows 而不是 POSIX(包括苹果电脑)。只需在任何地方使用正斜杠即可。

    【讨论】:

    • 问题并不总是关于用法,而是关于解析:例如,如果我得到一个路径,我如何得到它的父级不知道系统接受的路径分隔符的目录?
    • Windows 没有像 realpath 这样的功能来为您执行此操作?
    • 不完全是——有PathCanonicalize和相关的API,但是依赖(shlwapi.dll)太高级了,实际上没有用——它在内核模式下没用,而且它在用户模式下加载不必要的 DLL。更不用说它们甚至不能处理超过 260 个字符的路径。
    猜你喜欢
    • 2011-08-30
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-07
    相关资源
    最近更新 更多