Will this method of creating relative paths work?

Since .NET does not include an API for creating relative paths, I used the Uri method instead MakeRelativeUri. This works, but I came across several cases in which this is not due to the fact that Uri is hidden. So I also fixed this:

public static string MakeRelativePath(string basePath, string tgtPath) {
    return
        Uri.UnescapeDataString(
            new Uri(basePath, UriKind.Absolute)
                .MakeRelativeUri(new Uri(tgtPath, UriKind.Absolute))
            .ToString()
        ).Replace('/', Path.DirectorySeparatorChar);
}

These versions seem to work, but this leaves me with a bit of trouble: are there any valid paths to the local file system that could be corrupted by this gratuitous failure?

Related: How to get the relative path from the absolute path The answers to this question do not affect the problem of unusual characters and generally disappear, and therefore do not answer this question.

+3
source share
1

, , System.Uri PathDifference. Reflector . DOS URI, .

static string PathDifference(string path1, string path2)
{
    int c = 0;  //index up to which the paths are the same
    int d = -1; //index of trailing slash for the portion where the paths are the same

    while (c < path1.Length && c < path2.Length)
    {
        if (char.ToLowerInvariant(path1[c]) != char.ToLowerInvariant(path2[c]))
        {
            break;
        }

        if (path1[c] == '\\')
        {
            d = c;
        }

        c++;
    }

    if (c == 0)
    {
        return path2;
    }

    if (c == path1.Length && c == path2.Length)
    {
        return string.Empty;
    }


    System.Text.StringBuilder builder = new System.Text.StringBuilder();

    while (c < path1.Length)
    {
        if (path1[c] == '\\')
        {
            builder.Append(@"..\");
        }
        c++;
    }

    if (builder.Length == 0 && path2.Length - 1 == d)
    {
        return @".\";
    }

    return builder.ToString() + path2.Substring(d + 1);
}

, -, , , . , .

... , .

Path1                   Path2               Output
C:\test\path1\path2\    C:\test\            ..\..\
C:\test\path1\file      C:\test\            ..\
C:\test\path1\path2\    C:\                 ..\..\..\
C:\test\path1\path2\    D:\                 D:\
C:\test\path1\path2\    C:\test\path1\pathA ..\pathA
C:\test\                C:\test\    
C:\test\                C:\test\file        file
C:\test\file            C:\test\            .\
C:\test\path #1!\path2\ C:\test\            ..\..\
+4

All Articles