1. 介紹
為什麼需要類別 Path?
處理檔案不可避免要處理它們的路徑。路徑告訴程式究竟在哪裡尋找所需的檔案或資料夾。
在日常生活中你有地址:市 [城市名稱]、街 [街道名稱]、號 [門牌號]。對電腦來說,檔案路徑看起來大概是這樣:
"C:\Program Files\MyApp\data.txt"
或者,如果你偏好跨平台:
"/home/username/documents/data.txt"
但問題是:不同作業系統使用不同的分隔符,可能對長度或可用字元有限制。即使使用者手動輸入路徑也很容易出錯:不是每個人都知道 Windows 裡那詭異的雙反斜線(\\),或是 Unix 類系統的路徑以 / 開頭。
為了不自己重造輪子,.NET 提供了一個靜態類別 System.IO.Path,它負責解析、修改和拼接路徑。來更靠近地認識這位超級英雄吧!
Path 解決的主要任務
- 取得檔案的副檔名。
- 從完整路徑取得檔名或目錄名稱。
- 從片段建立絕對或相對路徑。
- 檢查路徑是否對當前作業系統有效。
- 替換檔案副檔名。
- 判斷基底目錄與父目錄。
- 跨平台處理路徑分隔符。
- 處理臨時檔案與目錄。
表格:Path 的主要方法與屬性
| 方法/屬性 | 用途 |
|---|---|
|
含副檔名的檔名 |
|
檔案的副檔名(例如 .txt) |
|
檔案所在資料夾的路徑 |
|
不含副檔名的檔名 |
|
安全且跨平台地拼接路徑段 |
|
變更檔案的副檔名 |
|
取得絕對路徑 |
|
路徑中不允許的字元 |
|
檔名中不允許的字元 |
|
系統臨時檔案資料夾的路徑 |
|
建立一個臨時檔案並回傳其路徑 |
|
目錄分隔符(例如 \ 或 /) |
|
替代的分隔符 |
|
環境變數中路徑的分隔符(; 或 :) |
2. 取得路徑的部分
幾乎所有 Path 類別的方法都是靜態的。你不需要建立實例 — 直接呼叫 Path.方法名(...) 就可以了。
最常用的工具有:GetFileName, GetDirectoryName, GetExtension, GetFileNameWithoutExtension。任何時候你可能需要擷取不含路徑的檔名、只看副檔名,或知道檔案在哪個資料夾。
範例:
using System;
using System.IO;
string path = @"C:\Projects\MyApp\data\info.json";
Console.WriteLine(Path.GetFileName(path)); // info.json
Console.WriteLine(Path.GetFileNameWithoutExtension(path)); // info
Console.WriteLine(Path.GetExtension(path)); // .json
Console.WriteLine(Path.GetDirectoryName(path)); // C:\Projects\MyApp\data
| 程式碼 | 結果 |
|---|---|
|
info.json |
|
|
|
.json |
|
info |
|
C:\Projects\MyApp\data |
3. 拼接路徑:Combine
新手最常犯的錯誤是用字串相加去拼路徑。別這樣做!
錯誤範例:
// 可能會出錯!
string fullPath = "C:\\Projects\\MyApp\\" + "data\\info.json";
如果忘了加上斜線或反斜線怎麼辦?或是用錯了分隔符?
正確的做法是使用 Path.Combine。
string folder = @"C:\Projects\MyApp";
string filename = "data\\info.json";
string fullPath = Path.Combine(folder, filename);
// 在任何平台上都會正確拼接路徑片段!
Console.WriteLine(fullPath); // C:\Projects\MyApp\data\info.json
處理相對路徑
如果傳入相對路徑,Path.Combine 會正確處理。盡量把路徑拆成段來處理!
string baseDir = "C:/work";
string subDir = "docs";
string file = "readme.txt";
string path = Path.Combine(baseDir, subDir, file);
// 結果: "C:/work/docs/readme.txt"(或用反斜線 —— 取決於平台)
給資深人的小知識:在 Path.Combine 內部會使用適合你作業系統的正確分隔符。Windows 用 \,Linux/Mac 用 /。你的程式會變得跨平台,即便你沒多想這點!
4. 驗證路徑有效性
有專門的方法:GetInvalidPathChars, GetInvalidFileNameChars。
假設使用者在介面輸入了檔名或路徑。怎麼確認字串不包含不允許的字元?直接問 Path 就行。
char[] invalidPathChars = Path.GetInvalidPathChars();
char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
string userInput = "data*?.txt";
foreach (char c in userInput)
{
if (Array.Exists(invalidFileNameChars, x => x == c))
{
Console.WriteLine($"不允許的檔名字元: {c}");
}
}
// 會輸出: 不允許的檔名字元: *
如果程式從使用者或不可信的來源取得路徑,這點尤其重要!
5. 有用的方法
改變檔案副檔名:ChangeExtension
有時候需要把檔案副檔名換成別的。只要一行就搞定!
string oldPath = @"C:\data\report.csv";
string newPath = Path.ChangeExtension(oldPath, ".bak");
Console.WriteLine(newPath); // C:\data\report.bak
ChangeExtension 只會改變尾部的副檔名,不會動路徑的其他部分。
取得絕對路徑:GetFullPath
如果路徑是相對的,可以用這個方法取得絕對(完整)路徑。
string relPath = @"..\..\logs\2024.log";
string absPath = Path.GetFullPath(relPath);
Console.WriteLine(absPath);
// 例如: C:\Projects\MyApp\logs\2024.log
實際結果依應用程式目前的工作目錄而定(Directory.GetCurrentDirectory())。
路徑分隔符:Path.DirectorySeparatorChar
記得在 Windows 分隔符是 \,在 Linux 是 /。
別自己想花招——用這些屬性:
- Path.DirectorySeparatorChar — 你作業系統上的主要目錄分隔符(在 Windows 為 '\\',在 Linux 為 '/')。
- Path.AltDirectorySeparatorChar — 替代分隔符(在 Windows 上 '/' 也能用)。
- Path.PathSeparator — 環境變數中路徑的分隔符(Windows 為 ';',Linux 為 ':')。
使用範例:
Console.WriteLine(Path.DirectorySeparatorChar); // \ (在 Windows)
Console.WriteLine(Path.AltDirectorySeparatorChar); // / (在 Windows)
Console.WriteLine(Path.PathSeparator); // ; (在 Windows)
這在你自己實作目錄遍歷等工具時會很有用!
6. 臨時檔案與目錄的處理
每個程式有時都需要臨時檔案——比如保存中間結果或做原子性更新。
- Path.GetTempPath() — 回傳系統的臨時檔案資料夾路徑。
- Path.GetTempFileName() — 建立一個具唯一名稱的臨時檔案並回傳其路徑。
範例:
string tempDir = Path.GetTempPath();
Console.WriteLine($"臨時檔案資料夾: {tempDir}");
string tempFile = Path.GetTempFileName();
Console.WriteLine($"建立了臨時檔案: {tempFile}");
這些方法可以避免名稱衝突,也不用你煩惱要把技術性檔案放在哪裡。
7. 常見錯誤與有趣的路徑陷阱
首先是習慣用字串相加去拼路徑。你可能會想:「欸,很簡單:folder + "\\\" + file 就行了!」結果在實務上會遇到雙分隔符、漏掉分隔符、或在 Linux 用了錯誤的分隔符。這些都不是 bug,而是你沒用 Path.Combine。
第二,忘記不允許的字元。例如使用者在檔名裡輸入了 *(「星號」)——那你就會遇到例外或錯誤。
第三,混淆相對路徑與絕對路徑,導致程式在你沒預期的地方找檔案,如 "notebook.txt" 並不是在你以為的目錄下。
建議:每次和檔案路徑打交道時——不管是拼接、解析、改副檔名、還是做錯誤防護——先問自己:「會不會有 Path 裡的方法能解決?」99% 的情況下答案是肯定的,這些方法已由 Microsoft 團隊在各種奇怪的 edge-case 上測試過。
GO TO FULL VERSION