引言
在做文件路徑處理時,經常需要對一個路徑的相對路徑進行操作,那麼如何拼合相對路徑以生成新的絕對路徑呢?
Path.Combine()方法
我們知道System.IO.Path是專門用來處理路徑的靜態類,它有一個Combine()方法就是用於拼接路徑的,我們來測試一下其拼接效果。
我們使用一個命令行程序進行測試,這裡要測試相對於文件C:abc123avatar.html的一系列相對路徑,測試代碼如下:
class Program
{
static string path = @"C:abc123avatar.html";
static void Main(string[] args)
{
Console.WriteLine(path);
Console.WriteLine("輸入相對路徑以完成合並:");
Console.WriteLine();
while (true)
{
Console.WriteLine("合並為:"+合並路徑(Console.ReadLine()));
Console.WriteLine();
}
}
private static string 合並路徑(string p)
{
return Path.Combine(Path.GetDirectoryName(path), p);
}
}
其中“合並路徑”方法的功能是先獲取文件的所在目錄,再與相對路徑拼合。
測試結果:
可以看到,常規的路徑拼合沒有問題,但是輸入“..”就沒有被正確處理為上級目錄,而是直接進行了合並,這不是我期望看到的。
怎樣做才能支持“..”形式的相對路徑呢?
利用Uri對象的構造函數
我發現Uri對象在構造時可以傳入一個基於的Uri及一個相對路徑以構造為新的Uri,而我們可以以“file://……”的形式來表示本地文件路徑,讓我們改動一下代碼,進行一下相對Uri的拼合測試。
改動後的代碼:
class Program
{
//static string path = @"C:abc123avatar.html";
static string path = @"file:///C:/abc/123/avatar.html";
static void Main(string[] args)
{
Console.WriteLine(path);
Console.WriteLine("輸入相對路徑以完成合並:");
Console.WriteLine();
while (true)
{
//Console.WriteLine("合並為:" + 合並路徑(Console.ReadLine()));
Console.WriteLine("合並為:" + 合並Uri(Console.ReadLine()));
Console.WriteLine();
}
}
private static string 合並路徑(string p)
{
return Path.Combine(Path.GetDirectoryName(path), p);
}
private static string 合並Uri(string p)
{
return new Uri(new Uri(path), p).AbsoluteUri;
}
}
測試結果:
好極了,完美支持“../”形式的相對路徑!
完善
那麼接下來的工作就是將路徑轉換為Uri形式,然後拼合相對路徑,再轉換回路徑形式就可以了。
轉換的時候僅僅是采取字符串處理的方法,改動後的代碼如下:
class Program
{
static string path = @"C:abc123avatar.html";
static void Main(string[] args)
{
Console.WriteLine(path);
Console.WriteLine("輸入相對路徑以完成合並:");
Console.WriteLine();
while (true)
{
Console.WriteLine("合並為:" + 合並路徑(Console.ReadLine()));
Console.WriteLine();
}
}
private static string 合並路徑(string p)
{
return new Uri(new Uri("file:///" + path.Replace("\", "/")), p.Replace("\", "/")).AbsoluteUri.Substring(8).Replace("/", "\");
}
}
測試結果:
結語
結果很令人滿意,但我總覺得這是個土方子、山寨辦法,誰有更簡便、正統點的方法嗎?
感謝天方這麼快就提出了正統的寫法:Path.GetFullPath(Path.Combin(@"C:ac","...text"));
我之前找了那麼久,又折騰那麼久,才弄出個山寨的來,實在汗顏啊,呵呵。