Reputation: 41861
Given paths like this:
C:\Temp\SomeDirectory\*.xml
I'd like to be able to distinguish the *.xml
from C:\Temp\SomeDirectory
However, I do not want a path to a directory that does not have a trailing slash to return its parent directory.
This means I want the following behaviour:
// Wildcard paths return directory
C:\Temp\SomeDirectory\*.csv -> C:\Temp\SomeDirectory
// Trailing slash paths return full path
C:\Temp\SomeDirectory\ -> C:\Temp\SomeDirectory
// Non-trailing slash paths to a directory return full path
C:\Temp\SomeDirectory -> C:\Temp\SomeDirectory
// Paths to a file return the directory
C:\Temp\SomeDirectory\SomeFileThatExists.csv -> C:\Temp\SomeDirectory
// Paths to a file without an extension (that exists) return the directory
C:\Temp\SomeDirectory\SomeFileThatExistsWithNoExt -> C:\Temp\SomeDirectory
// Paths to a non-existent path without a trailing slash are standard
// Either always clip the trailing part, or always leave it in
// (Can live with this one being C:\Temp\SomeDirectory)
C:\Temp\SomeDirectory\NonExistentObject -> C:\Temp\SomeDirectory\NonExistentObject
// Paths to a non-existent path with a trailing slash return the full path
C:\Temp\SomeDirectory\NonExistentObject\ -> C:\Temp\SomeDirectory\NonExistentObject
// Paths to a non-existent path with a file extension return the directory
C:\Temp\SomeDirectory\NonExistentFile.Ext -> C:\Temp\SomeDirectory
(I am not fussed if the return value has a trailing slash or not, although the method I put below consistently does not return a trailing slash)
My current code is something like this, and handles these cases:
public string GetDirectory(string path)
{
try
{
var f = new FileInfo(path); // Throws if invalid path, e.g. wildcards
// Existent directory
if (Directory.Exists(path))
{
// Full path must be a directory, so return full path
// Ensure to add a trailing slash, as if it's missing it will return parent directory
return Path.GetDirectoryName(path + '/');
}
// Non-existent directory (or ambiguous path without an extension or trailing slash)
if (!System.IO.File.Exists(path) && String.IsNullOrEmpty(Path.GetExtension(path)))
{
// Path is to a non-existent file (without an extension) or to a non-existent directory.
// As the path does not exist we will standardise and treat it as a directory.
return Path.GetDirectoryName(path + '/');
}
// Path is to a file, return directory
return Path.GetDirectoryName(path);
}
catch (ArgumentException)
{
// For wildcards/invalid paths, return the directory
// This maps C:\Dir\*.csv to C:\Dir
// Also maps C:\Dir&*A*#$!@& to C:\
return Path.GetDirectoryName(path);
}
}
Is there a better way to achieve this behaviour, or my ultimate goal of being able to get the "directory" from a path that may include wildcards?
Upvotes: 2
Views: 1301
Reputation: 20640
Do you have any control over the generation of the list of paths? If you could ensure that all paths to directories end with a trailing slash (which I believe is the convention) then the simple Path.GetDirectoryName(path)
will work for all these cases.
Upvotes: 2
Reputation: 8790
The problem I believe is that the Path methods are just string manipulation functions. I don't believe they actually go out and find whether you're looking at a directory or a file without an extension.
You will need to use the Directory or File class in conjunction to find out which it is and then manually change it accordingly.
Upvotes: 2