For example, how can I make this
"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt"
relative to this folder
"C:\RootFolder\SubFolder\"
if the expected result is
"MoreSubFolder\LastFolder\SomeFile.txt"
For example, how can I make this
"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt"
relative to this folder
"C:\RootFolder\SubFolder\"
if the expected result is
"MoreSubFolder\LastFolder\SomeFile.txt"
Yes, you can do that, it's easy, think of your paths as URIs:
Uri fullPath = new Uri(@"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt", UriKind.Absolute);
Uri relRoot = new Uri(@"C:\RootFolder\SubFolder\", UriKind.Absolute);
string relPath = relRoot.MakeRelativeUri(fullPath).ToString();
// relPath == @"MoreSubFolder\LastFolder\SomeFile.txt"
In your example, it's simply absPath.Substring(relativeTo.Length).
More elaborate example would require going back a few levels from the relativeTo, as follows:
"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt"
"C:\RootFolder\SubFolder\Sibling\Child\"
The algorithm to make a relative path would look as follows:
"C:\RootFolder\SubFolder\")relativeTo (in this case, it is 2: "Sibling\Child\")..\ for each remaining folderThe end result looks like this:
"..\..\MoreSubFolder\LastFolder\SomeFile.txt"
Here is my 5-cents without using any special Url class for that purpose.
Search for makeRelative in following git repository: https://github.com/tapika/syncProj/blob/8ea41ebc11f538a22ed7cfaf59a8b7e0b4c3da37/syncProj.cs#L1685
(Fixed version frozen once upon a time, search latest version separately)
I'll fix bugs if there is any.
Here is copy of same code as in link above:
/// <summary>
/// Rebases file with path fromPath to folder with baseDir.
/// </summary>
/// <param name="_fromPath">Full file path (absolute)</param>
/// <param name="_baseDir">Full base directory path (absolute)</param>
/// <returns>Relative path to file in respect of baseDir</returns>
static public String makeRelative(String _fromPath, String _baseDir)
{
String pathSep = "\\";
String fromPath = Path.GetFullPath(_fromPath);
String baseDir = Path.GetFullPath(_baseDir); // If folder contains upper folder references, they gets lost here. "c:\test\..\test2" => "c:\test2"
String[] p1 = Regex.Split(fromPath, "[\\\\/]").Where(x => x.Length != 0).ToArray();
String[] p2 = Regex.Split(baseDir, "[\\\\/]").Where(x => x.Length != 0).ToArray();
int i = 0;
for (; i < p1.Length && i < p2.Length; i++)
if (String.Compare(p1[i], p2[i], true) != 0) // Case insensitive match
break;
if (i == 0) // Cannot make relative path, for example if resides on different drive
return fromPath;
String r = String.Join(pathSep, Enumerable.Repeat("..", p2.Length - i).Concat(p1.Skip(i).Take(p1.Length - i)));
return r;
}