命名文件、路径和命名空间

文件支持的所有文件系统Windows文件和目录的概念来访问存储在磁盘或设备上的数据。 Windows文件和设备 I/O Windows API 的开发人员应了解文件和目录的名称的各种规则、约定和限制。

可以使用文件 I/O API 从磁盘、设备和网络共享访问数据。 文件和目录以及命名空间是路径概念的一部分,路径是在何处获取数据的字符串表示形式,无论数据来自磁盘、设备还是特定操作的网络连接。

某些文件系统(如 NTFS)支持链接文件和目录,这些链接文件和目录也遵循文件命名约定和规则,就像常规文件或目录一样。 有关其他信息,请参阅 硬链接和交接 点和 重新分析点和文件操作

有关其他信息,请参阅以下小节:

若要了解如何配置 Windows 10以支持长文件路径,请参阅最大路径长度限制

文件和目录名称

所有文件系统都遵循单个文件的相同常规命名约定:基文件名和可选扩展名,用一个时间段分隔。 但是,每个文件系统(如 NTFS、CDFS、exFAT、UDFS、FAT 和 FAT32)都可以对目录或文件路径中各个组件的构成有特定且不同的规则。 请注意, 目录 只是一个包含特殊属性的文件,它将它指定为目录,否则必须遵循与常规文件相同的命名规则。 由于"目录"一词只是就文件系统而言是指一种特殊类型的文件,因此一些参考资料将使用常规术语文件来包含目录和数据文件的概念。 因此,除非另行指定,否则文件的任何命名或使用规则或示例也应应用于目录。 术语 "路径 "是指一个或多个目录、反杠以及可能为卷名称。 有关详细信息,请参阅路径部分。

字符计数限制也可能不同,并且可能会因使用的文件系统和路径名称前缀格式而异。 由于支持后向兼容性机制,这进一步变得复杂。 例如,较旧的 MS-DOS FAT 文件系统最多支持 8 个字符作为基文件名,3 个字符用于扩展名,总共支持 12 个字符(包括点分隔符)。 这通常称为 8.3 文件名。 WINDOWS FAT 和 NTFS 文件系统不限于 8.3 文件名,因为它们具有长文件名支持 ,但仍 支持长文件名的 8.3 版本。

命名约定

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

  • 使用一个时间段将基文件名与目录或文件名称中的扩展名分隔。

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

  • 在卷名称中按要求使用反杠,例如,通用命名约定 (\ \ \ \ \ \ \ \ \ \ \ UNC) 名称的"C: "在"C: 路径文件中"或"服务器共享"。 有关 UNC 名称详细信息,请参阅 最大路径长度限制 部分。

  • 不要假定区分大小写。 例如,即使某些文件系统(如符合 POSIX 的文件系统) (可能将它们视为不同的名称,) 则它们是相同的。 请注意,NTFS 支持 POSIX 语义区分大小写,但这不是默认行为。 有关详细信息,请参阅 CreateFile

  • 卷 (驱动器号) 同样不区分大小写。 例如,"D:" \ 和"d:" \ 指同一卷。

  • 使用当前代码页中的任意字符作为名称,包括 Unicode 字符和扩展字符集 (128-255) 字符,但以下字符除外:

    • 以下保留字符:

      • <(小于)
      • >(大于)
      • : (冒号)
      • "(双引号)
      • /(正斜杠)
      • \ (反反)
      • | (竖线或竖线)
      • ? (问号)
      • * (星号)
    • 整数值零,有时称为 ASCII NUL 字符。

    • 整数表示形式在 1 到 31 范围内的字符,但允许使用这些字符的备用数据流除外。 有关文件流的信息,请参阅 文件流

    • 目标文件系统不允许的其他任何字符。

  • 使用时间段作为路径 中的 目录组件来表示当前目录,例如"。 \temp.txt"。 有关详细信息,请参阅 路径

  • 使用两个连续句点 (。。) 作为路径 中的 目录组件,以表示当前目录的父级,例如"."。 \temp.txt"。 有关详细信息,请参阅 路径

  • 请勿将以下保留名称用于文件名:

    CON、PRN、AUX、NUL、COM1、COM2、COM3、COM4、COM5、COM6、COM7、COM8、COM9、LPT1、LPT2、LPT3、LPT4、LPT5、LPT6、LPT7、LPT8 和 LPT9。 此外,请避免紧接扩展名后跟这些名称;例如,NUL.txt使用 。 有关详细信息,请参阅命名空间

  • 不要以空格或时间段结尾文件或目录名称。 尽管基础文件系统可能支持此类名称,但 Windows shell 和用户界面不支持。 但是,可以指定一个时间段作为名称的第一个字符。 例如,".temp"。

短名称与长名称

长文件名被视为超过短 MS-DOS 名称的任何文件名 (也称为 8.3) 命名约定。 创建长文件名时,Windows也可以创建一个短格式的名称(称为 8.3 别名或短名称)并存储在磁盘上。 可以出于系统范围内或指定卷的性能原因禁用此 8.3 别名,具体取决于特定的文件系统。

Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 在 Windows 7 和 Windows Server 2008 R2 之前,无法为指定的卷禁用 8.3 别名。

在许多文件系统上,文件名将包含一个 (~) ,该名称的每个组件太长,不符合 8.3 命名规则。

备注

并非所有文件系统都遵循 tilde 替换约定,并且可以将系统配置为禁用 8.3 别名生成,即使它们通常支持 8.3 别名生成。 因此,不要假设磁盘上已存在 8.3 别名。

若要从系统请求 8.3 文件名、长文件名或文件的完整路径,请考虑以下选项:

  • 若要获取长文件名的 8.3 格式,请使用 GetShortPathName 函数。
  • 若要获取短名称的长文件名版本,请使用 GetLongPathName 函数。
  • 若要获取文件的完整路径,请使用 GetFullPathName 函数。

在较新的文件系统(如 NTFS、exFAT、UDFS 和 FAT32)上,Windows 将长文件名存储在 Unicode 磁盘上,这意味着始终保留原始长文件名。 即使长文件名包含扩展字符,也是如此,而不考虑在磁盘读取或写入操作期间处于活动状态的代码页。

使用长文件名的文件可以在 NTFS 文件系统分区和 FAT Windows之间复制,而不会丢失任何文件名信息。 对于较旧的 MS-DOS FAT 和某些类型的 CDFS (CD-ROM) 文件系统,这可能不一定如此,具体取决于实际文件名。 在这种情况下,如果可能,将替换短文件名。

路径

指定文件的路径由一个或多个组件组成,由特殊字符 (反杠) 分隔,每个组件通常是目录名称或文件名,但下面讨论了一些值得注意的例外。 它通常对于系统对路径的开头(或前缀)的解释至关重要。 此前缀确定 路径 使用的命名空间,以及路径中的位置(包括最后一个字符)使用的特殊字符。

如果路径的组件是文件名,则它必须是最后一个组件。

路径的每个组件也将受为特定文件系统指定的最大长度约束。 一般情况下,这些规则分为两类 :short 和 long。 请注意,目录名称由文件系统存储为特殊类型的文件,但文件的命名规则也适用于目录名称。 总之,路径只是特定文件或目录名称的所有目录之间的层次结构的字符串表示形式。

完全限定路径与相对路径

对于Windows文件的 API 函数,文件名通常可以相对于当前目录,而某些 API 需要完全限定的路径。 如果文件名不是以下列之一开头,则文件名相对于当前目录:

  • 任何格式的 UNC 名称,始终以两个反 (字符 \ \ ) 。 有关更多信息,请参见下一节。
  • 带反杠的磁盘设计器,例如"C: \ "或"d: \ "。
  • 单个反杠,例如 \ "directory"或 \ "file.txt"。 这也称为绝对 路径

如果文件名以磁盘说明符开头,而不是冒号后的反杠开头,则解释为驱动器上具有指定字母的当前目录的相对路径。 请注意,当前目录可能是根目录,也可能不是根目录,具体取决于在磁盘上的最新"更改目录"操作期间设置为什么。 此格式的示例如下所示:

  • "C:tmp.txt"是指驱动器 C 上tmp.txt目录中名为"tmp.txt"的文件。
  • "C:tempdirtmp.txt"是指驱动器 C 上当前目录的子目录中 \ 的文件。

如果路径包含"双点",则路径也称相对路径;也就是说,路径的一个组件中同时有两个句点。 此特殊说明性说明用于表示当前目录上方的目录,也称为"父目录"。 此格式的示例如下所示:

  • "..\tmp.txt"指定名为 tmp.txt 的文件,该文件位于当前目录的父目录中。
  • "..\..\tmp.txt"指定一个文件,该文件是当前目录上方的两个目录。
  • "..\tempdirtmp.txt"指定名为 tmp.txt 的文件,该文件位于名为 tempdir 的目录中,该目录是当前目录的 \ 对等目录。

相对路径可以组合这两个示例类型,例如"C:."。 \tmp.txt"。 这很有用,因为尽管系统会跟踪当前驱动器以及该驱动器的当前目录,但如果系统具有多个驱动器号 (则无论哪个驱动器设计器设置为当前驱动器,它也会跟踪每个不同驱动器号) 中的当前目录。

最大路径长度限制

在版本 1607 之前Windows版本中Windows 10,路径的最大长度为 MAX _ PATH, 定义为 260 个字符。 在更高版本的 Windows中,更改注册表项或组策略工具才能删除限制。 有关 完整详细信息,请参阅最大路径 长度限制。

命名空间

在应用程序 API 中,有两种Windows类,通常称为 NT 命名空间Win32 命名空间。 NT 命名空间设计为其他子系统和命名空间可以存在的最低级别命名空间,包括 Win32 子系统和 Win32 命名空间。 POSIX 是在 NT 命名空间Windows构建的一个子系统的另一个示例。 早期版本的 Windows 还对某些特殊设备(例如通信 (串行和并行) 端口以及默认显示控制台)定义了多个预定义或保留的名称,作为现在称为 NT 设备命名空间的一部分,并且在当前版本的 Windows 中仍受支持,以确保向后兼容性。

Win32 文件命名空间

本部分和下一部分总结了 Win32 命名空间前缀和约定,并介绍了如何使用它们。 请注意,这些示例适用于 Windows API 函数,并不一定都适用于 Windows Shell 应用程序(如 Windows Explorer)。 因此,可能的路径范围比通常从 Windows shell 应用程序提供的路径范围更大,Windows利用这一点的应用程序可以使用这些命名空间约定进行开发。

对于文件 I/O,路径字符串的"?" 前缀指示 Windows API 禁用所有字符串分析,并将其后跟的字符串直接发送到 \ \ \ 文件系统。 例如,如果文件系统支持大型路径和文件名,则你可以超过其他 API 强制实施的 MAX _ PATH Windows限制。 有关正常最大路径限制详细信息,请参阅上一部分 的最大路径长度限制

由于它关闭路径字符串的自动扩展,因此"?" 前缀还允许在路径名称中使用 \ \ \ ".."和".",如果尝试对文件执行操作,而这些文件具有这些保留的相对路径说明符作为完全限定路径的一部分,则这非常有用。

许多(但不是所有)文件 I/O API 都支持 \ \ "?";你应该查看每个 API 的参考 \ 主题,以确保这一点。

请注意,应该使用 Unicode API 确保"?" 前缀允许 \ \ 超过 MAX \ _ PATH

Win32 设备命名空间

\ \ \ "."前缀将访问 Win32 设备命名空间,而不是 Win32 文件命名空间。 如果 API 支持此类访问,则直接完成对物理磁盘和卷的访问,而无需通过文件系统。 可以使用 CreateFileDefineDosDevice 函数 (磁盘外的其他许多设备,例如) 。

例如,如果要打开系统的串行通信端口 1,可以在调用 CreateFile 函数时使用"COM1"。 这样做是因为 COM1-COM9 是 NT 命名空间中保留名称的一部分,尽管使用 \ \ \ "."前缀也适用于这些设备名称。 相比之下,如果已安装 100 端口串行扩展板并想要打开 COM56,则不能使用"COM56"打开它,因为没有针对 COM56 的预定义 NT 命名空间。 将需要使用 "打开它 \ \ 。 \COM56",因为 \ \ "."直接转到 \ 设备命名空间,而不尝试查找预定义的别名。

使用 Win32 设备命名空间的另一个示例是将 CreateFile函数与 " \ \ 一起使用。 \PhysicalDisk X" (其中 X 是有效的整数值,) 或 " \ \ 。 \CdRom X"。 这样,你可以直接访问这些设备,同时绕过文件系统。 这很有效,因为这些设备名称是在枚举这些设备时由系统创建的,并且某些驱动程序还会在系统中创建其他别名。 例如,实现名称"C:"的设备驱动程序有自己的命名空间,该命名空间恰好 \ 也是文件系统。

通过 CreateFile函数的 API 通常使用"."前缀,因为 CreateFile 是一种用于打开文件和设备的函数,具体取决于 \ \ \ 所使用的参数。

如果正在使用 Windows API 函数,则应该使用 \ \ "."前缀仅访问 \ 设备,而不要访问文件。

大多数 API 不支持 ".";只有设计用于设备命名空间的 API \ \ \ 才能识别它。 请务必查看每个 API 的参考主题。

NT 命名空间

还有一些 API 允许使用 NT 命名空间约定,但对象管理器Windows在大多数情况下不需要使用。 为了说明这一点,使用 Windows Sysinternals WinObj工具在系统对象浏览器中浏览Windows命名空间非常有用。 运行此工具时,可以看到从根目录开始的 NT 命名空间,或 \ ""。 名为"Global?"的子文件夹 是 Win32 命名空间所在的位置。 命名设备对象驻留在"Device"子目录中的 NT 命名空间中。 还可以在此处找到 Serial0 和 Serial1,即表示系统上存在前两个 COM 端口的设备对象。 表示卷的设备对象将类似"HarddiskVolume1",但数字后缀可能会有所不同。 子目录"Harddisk0"下的名称"DR0"是表示磁盘的设备对象的示例,以此类比。

若要使这些设备对象可供 Windows 应用程序访问,设备驱动程序会创建一个符号链接 (Win32 命名空间中的符号链接) "Global?",指向其各自的设备对象。 例如,"全局?"下的 COM0 和 COM1 子目录只是 Serial0 和 Serial1 的符号链接,"C:"是 HarddiskVolume1 的符号链接,"Physicaldrive0"是 DR0 的符号链接,等等。 如果没有符号链接,指定的设备"Xxx"将不适用于任何使用 Win32 命名空间Windows应用程序,如前文所述。 但是,任何支持 NT 命名空间绝对路径(格式为"Device Xxx")的 API,都可能会向该设备打开 \ \ 句柄。

通过终端服务和虚拟机添加多用户支持后,进一步需要虚拟化 Win32 命名空间中的系统范围的根设备。 这是通过将名为"GLOBALROOT"的符号链接添加到 Win32 命名空间(可在"Global?"中查看)完成的。 之前讨论的 WinObj 浏览器工具的子目录,可以通过路径 \ \ "?" \GLOBALROOT"。 此前缀可确保它之后的路径看起来是系统对象管理器的真实根路径,而不是依赖于会话的路径。

文件系统功能比较