开发者

How do I compare relative file or directory paths in C#?

There was already a question about comparis开发者_StackOverflowon of file paths in C#. But the solution provided implies that I have absolute paths. Can anyone suggest a good solution for relative paths or point to something I have to be aware of when comparing paths (on windows).

For example:

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

Those strings mean the same path


The answer you linked in your post should actually work for you. GetFullPath doesn't just resolve full paths to an absolute path, but also resolves relative path to absolute paths. Just don't forget to use the code to provided in the linked answer to resolve trailing slashes and add code to replace / with \ (as mentioned by Henk)


As Henk points out there are some cases where the path might have to be cleaned up first (or refused as a valid path). This page describes valid file and path names. You might want to clean up the path before comparing it using something like this:

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

By looking at the DirectoryInfo API Reference the following should then work:

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

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

Basically just extracting the absolute path from the relative path, and comparing on the absolute.


Not really understood your question, I think, but:

How you gonna COMPARE them?

  1. All path in your system have the same unique root, no subpaths. Just compare if comparable paths strings are equal ( uniforming before it paths format, I mean '/' '\' symbols). Not very nice soluion, as one day you or manager may deside to have nested path and your solution wil brake.

  2. Just figure out the complete path and follow the solution provided in link.


You should try the solution proposed in this question : How can I compare (directory) paths in C#?

Path.GetFullPath() can take a relative path as an argument : http://msdn.microsoft.com/en-us/library/system.io.path.getfullpath.aspx


This piece of code normalizes a path (including relative path). Once paths are normalized, (case-insensitive) string comparison becomes equivalent of path comparison.

This specific implementation does not assume that the "/" equals "\", but you can easily remedy that by replacing "/" prior passing the string to this method....

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

}


you may want to look at the Uri class and its members. there are methods for combining and comparing relative paths there, and there's a short example of using MakeRelativeUri here.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜