Например, как я могу сделать это
"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt"
относительно этой папки
"C:\RootFolder\SubFolder\"
если ожидаемый результат
"MoreSubFolder\LastFolder\SomeFile.txt"
Например, как я могу сделать это
"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt"
относительно этой папки
"C:\RootFolder\SubFolder\"
если ожидаемый результат
"MoreSubFolder\LastFolder\SomeFile.txt"
Да, вы можете сделать это, легко, подумайте о своих путях как URI:
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"
В вашем примере это просто absPath.Substring(relativeTo.Length)
.
Более сложный пример потребует возврата нескольких уровней из relativeTo
, как показано ниже:
"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt"
"C:\RootFolder\SubFolder\Sibling\Child\"
Алгоритм для создания относительного пути будет выглядеть следующим образом:
"C:\RootFolder\SubFolder\"
)relativeTo
(в данном случае это 2: "Sibling\Child\"
)..\
для каждой оставшейся папкиКонечный результат выглядит следующим образом:
"..\..\MoreSubFolder\LastFolder\SomeFile.txt"
Вот мои 5 центов без использования для этого специального класса Url.
Найти makeRelative в следующем репозитории svn:
https://sourceforge.net/p/syncproj/code/HEAD/tree/syncProj.cs#l976
Я исправлю ошибки, если они есть.
Почему все эти сложные решения?
И с участием Ури? В самом деле? Вам не придется долго ждать первого исключения.
Там блеск в простоте.
Нет необходимости в дополнительном кластерном классе.
public static string BuildRelativePath(string absolutePath, string basePath)
{
return absolutePath.Substring(basePath.Length);
}
И на всякий случай вам не удастся всегда добавлять или всегда опускать закрывающий System.IO.Path.DirectorySeparatorChar в ваши строки или вы не можете не смешивать аргументы:
public static string FaultTolerantRelativePath(string absolutePath, string basePath)
{
if(absolutePath == null || basePath == null)
return null;
absolutePath = absolutePath.Replace(System.IO.Path.DirectorySeparatorChar, '/');
basePath = basePath.Replace(System.IO.Path.DirectorySeparatorChar, '/');
if (!basePath.EndsWith("/"))
basePath += "/";
if (!absolutePath.EndsWith("/"))
absolutePath += "/";
if (absolutePath.Length < basePath.Length)
throw new ArgumentException("absolutePath.Length < basePath.Length ? This can't be. You mixed up absolute and base path.");
string resultingPath = absolutePath.Substring(basePath.Length);
resultingPath = resultingPath.Replace('/', System.IO.Path.DirectorySeparatorChar);
return resultingPath;
}