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
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).
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.
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.
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?
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.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With