命名檔案、路徑和命名空間

Windows 支援的所有文件系統都會使用檔案和目錄的概念來存取儲存在磁碟或裝置上的數據。 使用適用於檔案和裝置 I/O 之 Windows API 的 Windows 開發人員應該瞭解檔案和目錄名稱的各種規則、慣例和限制。

您可以使用檔案 I/O API,從磁碟、裝置和網路共用存取數據。 檔案和目錄以及命名空間是路徑概念的一部分,這是從磁碟或裝置或特定作業的網路連線取得數據的字串表示法。

某些文件系統,例如 NTFS,支援連結的檔案和目錄,這也會遵循檔案命名慣例和規則,就像一般檔案或目錄一樣。 如需詳細資訊,請參閱 硬式連結和連接點重新剖析點和檔案作業

若要瞭解如何設定 Windows 以支援長檔案路徑,請參閱 路徑長度上限限制

檔案和目錄名稱

所有文件系統都遵循個別檔案的相同一般命名慣例:基底檔名和選擇性擴展名,並以句號分隔。 不過,每個文件系統,例如NTFS、CDFS、exFAT、UDFS、FAT和F2,都可以有目錄或檔案路徑中個別元件形成的特定和不同規則。 請注意, 目錄 只是將目錄指定為目錄的特殊屬性,但必須遵循與一般檔案相同的所有命名規則。 由於目錄一詞只會參考文件系統所關注的特殊文件類型,因此某些參考數據會使用一般詞彙檔案來包含目錄和數據檔的概念,例如。 因此,除非另有指定,否則檔案的任何命名或使用規則或範例也應該套用至目錄。 「路徑」一詞是指一或多個目錄、反斜杠,以及可能為磁碟區名稱。 如需詳細資訊,請參閱 路徑 一節。

字元計數限制也可能不同,而且會根據使用的文件系統和路徑名稱前置詞格式而有所不同。 支援回溯相容性機制會進一步複雜。 例如,舊版 MS-DOS FAT 檔系統最多支援 8 個字元的基底檔名和 3 個字元的擴展名,總共有 12 個字元,包括點分隔符。 這通常稱為 8.3 檔名。 Windows FAT 和 NTFS 檔案系統不限於 8.3 檔名,因為它們具有 長檔名支援,但仍支援 8.3 版的長檔名。

命名規範

下列基本規則可讓應用程式建立及處理檔案和目錄的有效名稱,而不論檔案系統為何:

  • 使用句點分隔基底檔名與目錄或檔案名稱中的擴展名。

  • 使用反斜杠 (\) 來分隔路徑元件。 反斜杠會將檔名與路徑分割,並將一個目錄名稱從路徑中的另一個目錄名稱分割。 您無法在實際檔案或目錄的名稱中使用反斜杠,因為它是將名稱分隔成元件的保留字元。

  • 使用作為磁碟區名稱部分的反斜杠,例如“C:\path\file” 中的 “C:\” 或 “\\server\share” 中的 “\\server\share” 作為通用命名約定 (UNC) 名稱的 “\\server\share”。 如需 UNC 名稱的詳細資訊,請參閱 路徑長度上限限制 一節。

  • 請勿假設區分大小寫。 例如,假設 OSCAR、奧斯卡和奧斯卡的名稱相同,即使某些文件系統(例如 POSIX 相容的文件系統)可能會將它們視為不同。 請注意,NTFS 支援區分大小寫的 POSIX 語意,但這不是預設行為。 如需詳細資訊,請參閱 CreateFile

  • 磁碟區指定符(驅動器號)同樣不區分大小寫。 例如,“D:\” 和 “d:\” 是指相同的磁碟區。

  • 針對名稱使用目前代碼頁中的任何字元,包括擴充字元集中的 Unicode 字元和字元(128-255),但下列除外:

    • 下列保留字元:

      • < (小於)
      • > (大於)
      • : (冒號)
      • " (雙引號)
      • / (正斜線)
      • \ (反斜線)
      • |(垂直橫條或管道)
      • ? (問號)
      • * (星號)
    • 整數值零,有時稱為 ASCII NUL 字元。

    • 整數表示範圍從 1 到 31 的字元,但允許這些字元的替代數據流除外。 如需檔案數據流的詳細資訊,請參閱 檔案數據流

    • 目標檔案系統不允許的任何其他字元。

  • 使用句點做為路徑中的目錄 元件 來代表當前目錄,例如 “.\temp.txt”。 如需詳細資訊,請參閱 路徑

  • 使用兩個連續句號 (..) 做為路徑中的目錄 元件 ,代表目前目錄的父代,例如 “.. 。\temp.txt”。 如需詳細資訊,請參閱 路徑

  • 請勿使用下列保留名稱作為檔案名:

    CON、PRN、AUX、NUL、COM0、COM1、COM2、COM3、COM4、COM5、COM6、COM7、COM8、COM9、COM1、LPT0、LPT1、LPT2、LPT3、LPT4、LPT5、LPT6、LPT7、LPT8、LPT9、LPT≦、LPT1、LPT1 和 LPT≦。 也請避免這些名稱緊接在延伸模組後面;例如,NUL.txt和NUL.tar.gz都相當於 NUL。 如需詳細資訊,請參閱命名空間

    注意

    Windows 會辨識 8 位 ISO/IEC 8859-1 上標數位 1、𓲴 和 1 個數位,並將其視為 COM# 和 LPT# 裝置名稱的有效部分,使其保留在每個目錄中。 例如, echo test > COM¹ 無法建立檔案。

  • 請勿以空格或句號結束檔案或目錄名稱。 雖然基礎文件系統可能支援這類名稱,但 Windows 殼層和使用者介面則不支援。 不過,可以接受指定句號做為名稱的第一個字元。 例如,“.temp”。

簡短與長名稱

長檔名會被視為任何超過簡短 MS-DOS(也稱為 8.3) 樣式命名慣例的檔名。 當您建立長檔名時,Windows 也可能建立名稱的簡短 8.3 格式,稱為 8.3 別名 或簡短名稱,並將它儲存在磁碟上。 基於整個系統或指定磁碟區的效能考慮,可以停用此8.3別名,視特定文件系統而定。

Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 在 Windows 7 和 Windows Server 2008 R2 之前,無法針對指定的磁碟區停用 8.3 別名。

在許多文件系統上,檔名將會在名稱的每個元件中包含一個底線(~),而該元件太長而不符合8.3命名規則。

注意

並非所有文件系統都遵循並排取代慣例,而且系統可以設定為停用 8.3 別名產生,即使它們通常支援它也一樣。 因此,請勿假設 8.3 別名已存在於磁碟上。

若要從系統要求 8.3 檔名、長檔名或檔案的完整路徑,請考慮下列選項:

在較新的文件系統上,例如NTFS、exFAT、UDFS和FS和FS和Findows會將長檔名儲存在Unicode的磁碟上,這表示一律會保留原始的長檔名。 即使長檔名包含擴充字元,也是如此,不論磁碟讀取或寫入作業期間作用中的代碼頁為何。

使用長檔名的檔案可以在NTFS檔系統磁碟分區與Windows FAT檔系統分割之間複製,而不會遺失任何檔名資訊。 根據實際的檔名,較舊的 MS-DOS FAT 和某些類型的 CDFS (CD-ROM) 檔案系統可能不是這樣。 在此情況下,會盡可能取代簡短檔名。

路徑

指定檔案的路徑是由一或多個元件所組成,以特殊字元(反斜杠)分隔,每個元件通常都是目錄名稱或檔名,但以下討論的一些值得注意的例外狀況。 對於系統對路徑的解譯,路徑的開頭或 前置詞通常很重要。 此前置詞會 決定路徑所使用的命名空間 ,以及路徑內哪個位置使用的特殊字元,包括最後一個字元。

如果路徑的元件是檔名,它必須是最後一個元件。

路徑的每個元件也會受限於針對特定文件系統指定的長度上限。 一般而言,這些規則分為兩個類別: 。 請注意,檔案系統會將目錄名稱儲存為特殊類型的檔案,但檔案的命名規則也適用於目錄名稱。 總而言之,路徑只是特定檔案或目錄名稱存在之所有目錄之間的階層字串表示。

完整與相對路徑

對於操作檔案的 Windows API 函式,檔名通常可以相對於目前目錄,而某些 API 需要完整路徑。 如果檔案名稱不是以下欄其中一項開頭,則檔名會相對於目前目錄:

  • 任何格式的 UNC 名稱,一律以兩個反斜杠字元 (“\\” 開頭) 如需詳細資訊,請參閱一節。
  • 具有反斜杠的磁碟指示項,例如 “C:\” 或 “d:\”。
  • 單一反斜杠,例如 “\directory” 或 “\file.txt”。 這也稱為 絕對路徑

如果檔名開頭只有磁碟指示項,但不是冒號之後的反斜杠,則會將它解譯為磁碟驅動器上具有指定字母之目前目錄的相對路徑。 請注意,目前目錄可能或可能不是根目錄,取決於它在磁碟上最近「變更目錄」作業期間所設定的內容。 此格式的範例如下:

  • “C:tmp.txt” 是指磁碟驅動器 C 上目前目錄中名為 “tmp.txt” 的檔案。
  • “C:tempdir\tmp.txt” 是指磁碟驅動器 C 上目前目錄的子目錄中的檔案。

如果路徑包含「雙點」,則路徑也會是相對路徑;也就是說,在路徑的一個元件中,兩個句點在一起。 這個特殊規範可用來表示目前目錄上方的目錄,否則稱為「父目錄」。 此格式的範例如下:

  • "..\tmp.txt“ 指定名為 tmp.txt的檔案,該檔案位於目前目錄的父系中。
  • "..\..\tmp.txt“ 指定位於目前目錄上方兩個目錄的檔案。
  • "..\tempdir\tmp.txt“ 指定名為 tmp.txt 的檔案,該檔案位於名為 tempdir 的目錄中,該目錄是目前目錄的對等目錄。

相對路徑可以結合這兩個範例類型,例如 “C:.。\tmp.txt”。 這很有用,因為雖然系統會追蹤目前的磁碟驅動器以及該磁碟驅動器的目前目錄,但它也會追蹤每個不同驅動器號中的目前目錄(如果您的系統有一個以上),而不論哪個磁碟驅動器指示項設定為目前的磁碟驅動器。

路徑長度上限

在 Windows 10 版本 1607 之前的 Windows 版本中,路徑的最大長度是 MAX_PATH,定義為 260 個字元。 在更新版本的 Windows 中,需要變更登錄機碼或使用組策略工具來移除限制。 如需完整詳細數據,請參閱 路徑長度上限限制

命名空間

Windows API 中使用的命名空間慣例有兩個主要類別,通常稱為 NT 命名空間Win32 命名空間。 NT 命名空間是設計成其他子系統和命名空間可以存在的最低層級命名空間,包括 Win32 子系統,以及 Win32 命名空間。 POSIX 是 Windows 中建置在 NT 命名空間之上的子系統的另一個範例。 舊版 Windows 也為某些特殊裝置定義數個預先定義或保留的名稱,例如通訊(序列和平行)埠,以及預設的顯示控制台,做為現在稱為 NT 裝置命名空間的一部分,而且目前版本的 Windows 仍支援回溯相容性。

Win32 檔案命名空間

本節和下一節摘要說明 Win32 命名空間前置詞和慣例,說明如何使用它們。 請注意,這些範例適用於搭配 Windows API 函式使用,而且不一定會使用 Windows Shell 應用程式,例如 Windows 檔案總管。 因此,有比通常可從 Windows 殼層應用程式取得的可能路徑範圍更廣,而利用此方式的 Windows 應用程式可以使用這些命名空間慣例來開發。

對於檔案 I/O,路徑字串的 “\?\” 前置詞會告知 Windows API 停用所有字串剖析,並將緊接著的字串直接傳送至文件系統。 例如,如果文件系統支援大型路徑和檔名,您可以超過 Windows API 所強制執行的MAX_PATH 限制。 如需一般最大路徑限制的詳細資訊,請參閱上一節 最大路徑長度限制

因為它會關閉路徑字串的自動展開,所以 “\?\” 前置詞也允許在路徑名稱中使用 “..” 和 “.”,如果您嘗試在具有這些保留相對路徑規範的檔案上執行作業,這非常有用。

許多但並非所有檔案 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 函式搭配 “\.\PhysicalDriveX” (其中 X 是有效的整數值)或 “\.\CdRomX”。 這可讓您直接存取這些裝置,略過文件系統。 這可運作,因為這些裝置名稱是由系統建立,因為這些裝置是列舉的,有些驅動程式也會在系統中建立其他別名。 例如,實作 “C:\” 名稱的裝置驅動程式有自己的命名空間,也會碰巧是文件系統。

透過 CreateFile 函式的 API 通常會使用 “\\.\” 前置詞,因為 CreateFile 是用來開啟檔案和裝置的函式,視您使用的參數而定。

如果您正在使用 Windows 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??” 中建立符號連結 (symlink),以指向其各自的裝置物件。 例如,在 “Global??” 子目錄中的 COM0 和 COM1 只是與 Serial0 和 Serial1 的符號連結,“C:” 是 HarddiskVolume1 的符號連結,“Physicaldrive0” 是 DR0 的符號連結,依故。 如果沒有符號連結,任何使用 Win32 命名空間慣例的 Windows 應用程式將無法使用指定的裝置 「Xxx」,如先前所述。 不過,您可以使用支援 “\Device\Xxx” 格式 NT 命名空間絕對路徑的任何 API,開啟該裝置的句柄。

透過終端機服務和虛擬機新增多使用者支援,進一步需要虛擬化 Win32 命名空間內的全系統根裝置。 這可藉由將名為 「GLOBALROOT」 的符號連結新增至 Win32 命名空間來完成,您可以在先前討論的 WinObj 瀏覽器工具的 “Global??” 子目錄中看到,而且可以透過路徑 “\\?\GLOBALROOT” 進行存取。 此前置詞可確保其後面的路徑會在系統物件管理員的真正根路徑中尋找,而不是會話相依路徑。

另請參閱