Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

There was already a question about comparison 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

like image 817
username Avatar asked Aug 23 '11 09:08

username


People also ask

What is the difference between path and relative path?

An absolute path is defined as specifying the location of a file or directory from the root directory(/). In other words,we can say that an absolute path is a complete path from start of actual file system from / directory. Relative path is defined as the path related to the present working directly(pwd).

What is a relative directory path?

A relative path is a way to specify the location of a directory relative to another directory. For example, suppose your documents are in C:\Sample\Documents and your index is in C:\Sample\Index. The absolute path for the documents would be C:\Sample\Documents.

Should I use relative or absolute paths?

If you do a lot of testing and move content frequently between domains, then relative links are the best solution. Absolute paths are more secure, protect content, and prevent duplicate pages. The main point is that the link format you prefer should be applied to all URLs on the site.


5 Answers

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)

like image 184
Michael Avatar answered Oct 07 '22 11:10

Michael


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.

like image 29
filip-fku Avatar answered Oct 07 '22 11:10

filip-fku


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.

like image 30
Tigran Avatar answered Oct 07 '22 12:10

Tigran


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

like image 32
mathieu Avatar answered Oct 07 '22 10:10

mathieu


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;

}
like image 22
Branko Dimitrijevic Avatar answered Oct 07 '22 12:10

Branko Dimitrijevic