Path.Combine absolute with relative path strings

后端 未结 7 1255
旧时难觅i
旧时难觅i 2020-11-27 05:08

I\'m trying to join a Windows path with a relative path using Path.Combine.

However, Path.Combine(@\"C:\\blah\",@\"..\\bling\") returns C:\\blah\\

相关标签:
7条回答
  • 2020-11-27 05:13
    
    Path.GetFullPath(@"c:\windows\temp\..\system32")?
    
    
    0 讨论(0)
  • 2020-11-27 05:14

    Call Path.GetFullPath on the combined path http://msdn.microsoft.com/en-us/library/system.io.path.getfullpath.aspx

    > Path.GetFullPath(Path.Combine(@"C:\blah\",@"..\bling"))
    C:\bling
    

    (I agree Path.Combine ought to do this by itself)

    0 讨论(0)
  • 2020-11-27 05:18

    Path.GetFullPath() does not work with relative paths.

    Here's the solution that works with both relative + absolute paths. It works on both Linux + Windows and it keeps the .. as expected in the beginning of the text (at rest they will be normalized). The solution still relies on Path.GetFullPath to do the fix with a small workaround.

    It's an extension method so use it like text.Canonicalize()

    /// <summary>
    ///     Fixes "../.." etc
    /// </summary>
    public static string Canonicalize(this string path)
    {
        if (path.IsAbsolutePath())
            return Path.GetFullPath(path);
        var fakeRoot = Environment.CurrentDirectory; // Gives us a cross platform full path
        var combined = Path.Combine(fakeRoot, path);
        combined = Path.GetFullPath(combined);
        return combined.RelativeTo(fakeRoot);
    }
    private static bool IsAbsolutePath(this string path)
    {
        if (path == null) throw new ArgumentNullException(nameof(path));
        return
            Path.IsPathRooted(path)
            && !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal)
            && !Path.GetPathRoot(path).Equals(Path.AltDirectorySeparatorChar.ToString(), StringComparison.Ordinal);
    }
    private static string RelativeTo(this string filespec, string folder)
    {
        var pathUri = new Uri(filespec);
        // Folders must end in a slash
        if (!folder.EndsWith(Path.DirectorySeparatorChar.ToString())) folder += Path.DirectorySeparatorChar;
        var folderUri = new Uri(folder);
        return Uri.UnescapeDataString(folderUri.MakeRelativeUri(pathUri).ToString()
            .Replace('/', Path.DirectorySeparatorChar));
    }
    
    0 讨论(0)
  • 2020-11-27 05:28

    Be careful with Backslashes, don't forget them (neither use twice:)

    string relativePath = "..\\bling.txt";
    string baseDirectory = "C:\\blah\\";
    //OR:
    //string relativePath = "\\..\\bling.txt";
    //string baseDirectory = "C:\\blah";
    //THEN
    string absolutePath = Path.GetFullPath(baseDirectory + relativePath);
    
    0 讨论(0)
  • 2020-11-27 05:30

    What Works:

    string relativePath = "..\\bling.txt";
    string baseDirectory = "C:\\blah\\";
    string absolutePath = Path.GetFullPath(baseDirectory + relativePath);
    

    (result: absolutePath="C:\bling.txt")

    What doesn't work

    string relativePath = "..\\bling.txt";
    Uri baseAbsoluteUri = new Uri("C:\\blah\\");
    string absolutePath = new Uri(baseAbsoluteUri, relativePath).AbsolutePath;
    

    (result: absolutePath="C:/blah/bling.txt")

    0 讨论(0)
  • 2020-11-27 05:33

    This will give you exactly what you need (path does NOT have to exist for this to work)

    DirectoryInfo di = new DirectoryInfo(@"C:\blah\..\bling");
    string cleanPath = di.FullName;
    
    0 讨论(0)
提交回复
热议问题