2013年1月15日 星期二

[C#] 使用 Path.Combine 需注意事項

本來以為 Path.Combine 可以方便的幫忙處理所有狀況,但使用上卻不如預期,查詢了一下發現,原來 Path.Combine 內部主要處理幾件事
1. 判斷兩個路徑是否合法 (null 或特殊字元)
2. 判斷第二個路徑是否為根目錄
3. 第一個路徑最後是否有 "目錄分隔符號"

常常會照成使用錯誤的就是第 2 項,他會用 Path.IsPathRooted 去檢查,
若回傳為 True 那麼 Combine 的結果直接回傳 "第二個路徑",
而 Path.IsPathRooted 判斷的依據,就是看
第一個字元是否為 "目錄分隔符號" (ex: "\", "/") 或
第二個字元是否為 VolumeSeparatorChar (ex: "C:")

因此在使用 Path.Combine 時最好將第二個參數做判斷後再使用,
方法可如下:

        private string GetCombinedPath(string path)
        {
            // If the path is null, it'll return empty string.
            if (string.IsNullOrEmpty(path))
            {
                return string.Empty;
            }

            // If the path is not rooted, it'll return the original path.
            if (!Path.IsPathRooted(path))
            {
                return path;
            }

            // If the path is rooted and its length is one, it'll return the empty string.
            // Ex: "\\", "/"
            if (path.Length == 1)
            {
                return string.Empty;
            }

            // If the path is rooted and its length is larger than one, it'll remove the separator char.
            // EX: "\\Folder\file.txt", "/Folder/file.txt"
            if (path[0] == Path.DirectorySeparatorChar ||
                path[0] == Path.AltDirectorySeparatorChar)
            {
                return path.Substring(1);
            }

            // EX: "C:\\Folder\file.txt"
            if (path[1] == Path.VolumeSeparatorChar)
            {
                return GetCombinedPath(path.Substring(2));
            }

           // It should not reach the area.
            return string.Empty;
        }