Подтвердить что ты не робот

Как сделать абсолютный путь относительно определенной папки?

Например, как я могу сделать это

"C:\RootFolder\SubFolder\MoreSubFolder\LastFolder\SomeFile.txt"

относительно этой папки

"C:\RootFolder\SubFolder\"

если ожидаемый результат

"MoreSubFolder\LastFolder\SomeFile.txt"
4b9b3361

Ответ 1

Да, вы можете сделать это, легко, подумайте о своих путях как 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"

Ответ 2

В вашем примере это просто 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"

Ответ 3

Вот мои 5 центов без использования для этого специального класса Url.

Найти makeRelative в следующем репозитории svn:

https://sourceforge.net/p/syncproj/code/HEAD/tree/syncProj.cs#l976

Я исправлю ошибки, если они есть.

Ответ 4

Почему все эти сложные решения?
И с участием Ури? В самом деле? Вам не придется долго ждать первого исключения.
Там блеск в простоте.

Нет необходимости в дополнительном кластерном классе.

    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;
}