Как сравнить относительные пути к файлам или каталогам в C #? - PullRequest
7 голосов
/ 23 августа 2011

Уже был вопрос о сравнении путей к файлам в C #. Но предоставленное решение подразумевает, что у меня есть абсолютные пути. Может кто-нибудь предложить хорошее решение для относительных путей или указать на то, что я должен знать при сравнении путей (в окнах).

Например:

  • share/logs
  • share\logs
  • share/logs\

Эти строки означают один и тот же путь

Ответы [ 6 ]

3 голосов
/ 23 августа 2011

Ответ, который вы указали в своем сообщении, должен работать на вас.GetFullPath не только разрешает полные пути к абсолютному пути, но также разрешает относительный путь к абсолютным путям.Только не забудьте использовать код, указанный в связанном ответе, для разрешения косых черт и добавить код для замены / на \ (как упомянуто Хенком)

2 голосов
/ 23 августа 2011

Не очень понял ваш вопрос, я думаю, но:

Как ты их сравнишь?

  1. Все пути в вашей системе имеют одинаковый уникальный корень, без подпутей. Просто сравните, если сопоставимые строки путей равны (в форме перед форматированием путей, я имею в виду символы '/' '\'). Не очень хорошее решение, так как однажды вы или менеджер можете решить, что у вас есть вложенный путь и ваше решение.

  2. Просто выясните полный путь и следуйте решению, указанному в ссылке.

2 голосов
/ 23 августа 2011

Как указывает Хенк, в некоторых случаях сначала может потребоваться очистить путь (или отклонить как допустимый путь). Эта страница описывает допустимые имена файлов и путей.Возможно, вы захотите очистить путь перед его сравнением, используя что-то вроде этого:

string FormatPath(string path){
    string result = path.Replace("/","\\");
    result = result.TrimStart("\\");
    return result;
}

При просмотре справочника по API DirectoryInfo должно работать следующее:

DirectoryInfo d1 = new DirectoryInfo(FormatPath("share/logs")));
DirectoryInfo d2 = new DirectoryInfo(FormatPath("share\logs")));

if(d1.FullName.Equals(d2.FullName)){
    // They are the same
}

По сути, просто извлекаем абсолютный путь из относительного и сравниваем с абсолютным.

1 голос
/ 23 августа 2011

Этот фрагмент кода нормализует путь (включая относительный путь).Как только пути нормализованы, сравнение строк (без учета регистра) становится эквивалентным сравнению путей.

Эта конкретная реализация не предполагает, что "/" равно "\", но вы можете легко исправить это, заменив "/"перед передачей строки этому методу ....

/// <summary>
///     Converts a path in a form suitable for comparison with other paths.
/// </summary>
/// <remarks>
///     <para>
///         In general case, two equivalent paths do not necessarily have the same string
///         representation. However, after subjecting them to this method, they will have
///         (case-insensitively) equal string representations.
///     </para>
///     <para>
///         Removes ".." and "." and always trims trailing path separator (except for paths
///         in format "X:\" or "\"). Does not change case.
///     </para>
///     <para>
///         This method does not attempt to validate the path (since its purpose is only to
///         make paths comparable as strings), so some logically incorrect paths will pass
///         through it unscathed. Examples of such paths include: "C:\..", "\..",
///         "\\machine\c$\..", "\\machine\c$\..\.." etc...
///     </para>
/// </remarks>
/// <returns>
///     Normalized path. Empty or <c>null</c> <paramref name="path"/> results in empty or
///     <c>null</c> result.
/// </returns>
/// <seealso cref="PathComparer"/>
public static string NormalizePath(string path) {

    if (string.IsNullOrEmpty(path))
        return path;

    // Remove path root.
    string path_root = Path.GetPathRoot(path);
    path = path.Substring(path_root.Length);

    string[] path_components = path.Split(Path.DirectorySeparatorChar);

    // "Operating memory" for construction of normalized path.
    // Top element is the last path component. Bottom of the stack is first path component.
    Stack<string> stack = new Stack<string>(path_components.Length);

    foreach (string path_component in path_components) {

        if (path_component.Length == 0)
            continue;

        if (path_component == ".")
            continue;

        if (path_component == ".." && stack.Count > 0 && stack.Peek() != "..") {
            stack.Pop();
            continue;
        }

        stack.Push(path_component);

    }

    string result = string.Join(new string(Path.DirectorySeparatorChar, 1), stack.Reverse().ToArray());
    result = Path.Combine(path_root, result);

    return result;

}
1 голос
/ 23 августа 2011

Вам следует попробовать решение, предложенное в этом вопросе: Как я могу сравнить (каталог) пути в C #?

Path.GetFullPath () может принять относительный путь в качестве аргумента:http://msdn.microsoft.com/en-us/library/system.io.path.getfullpath.aspx

0 голосов
/ 23 августа 2011

Вы можете посмотреть на класс Uri и его членов. там есть методы для объединения и сравнения относительных путей, и есть короткий пример использования MakeRelativeUri здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...