Or, if you need to do something with each folder, have a look at the System.IO.DirectoryInfo class. It also has a Parent property that allows you to navigate to the parent directory.
There are a few ways that a file path can be represented. You should use the System.IO.Path class to get the separators for the OS, since it can vary between UNIX and Windows. Also, most (or all if I'm not mistaken) .NET libraries accept either a '\' or a '/' as a path separator, regardless of OS. For this reason, I'd use the Path class to split your paths. Try something like the following:
There is no empty element in the returned array if the path itself ends in a (back)slash (e.g. "\foo\bar\"). However, you will have to be sure that yourPath is really a directory and not a file. You can find out what it is and compensate if it is a file like this:
I believe this covers all bases without being too pedantic. It will return a string[] that you can iterate over with foreach to get each directory in turn.
If you want to use constants instead of the @"\/" magic string, you need to use
var separators = new char[] {
Path.DirectorySeparatorChar,
Path.AltDirectorySeparatorChar
};
and then use separators instead of @"\/" in the code above. Personally, I find this too verbose and would most likely not do it.
Realise this is an old post, but I came across it looking - in the end I decided apon the below function as it sorted what I was doing at the time better than any of the above:
private static List<DirectoryInfo> SplitDirectory(DirectoryInfo parent)
{
if (parent == null) return null;
var rtn = new List<DirectoryInfo>();
var di = parent;
while (di.Name != di.Root.Name)
{
rtn.Add(di);
di = di.Parent;
}
rtn.Add(di.Root);
rtn.Reverse();
return rtn;
}
public static IEnumerable<string> Split(this DirectoryInfo path)
{
if (path == null)
throw new ArgumentNullException("path");
if (path.Parent != null)
foreach(var d in Split(path.Parent))
yield return d;
yield return path.Name;
}
Here's a modification of Wolf's answer that leaves out the root and fixes what seemed to be a couple of bugs. I used it to generate a breadcrumbs and I didn't want the root showing.
this is an extension of the DirectoryInfo type.
public static List<DirectoryInfo> PathParts(this DirectoryInfo source, string rootPath)
{
if (source == null) return null;
DirectoryInfo root = new DirectoryInfo(rootPath);
var pathParts = new List<DirectoryInfo>();
var di = source;
while (di != null && di.FullName != root.FullName)
{
pathParts.Add(di);
di = di.Parent;
}
pathParts.Reverse();
return pathParts;
}
Inspired by the earlier answers, but simpler, and without recursion. Also, it does not care what the separation symbol is, as Dir.Parent covers this:
/// <summary>
/// Split a directory in its components.
/// Input e.g: a/b/c/d.
/// Output: d, c, b, a.
/// </summary>
/// <param name="Dir"></param>
/// <returns></returns>
public static IEnumerable<string> DirectorySplit(this DirectoryInfo Dir)
{
while (Dir != null)
{
yield return Dir.Name;
Dir = Dir.Parent;
}
}
Either stick this in a static class to create a nice extension method, or just leave out the this (and static).
Usage example (as an extension method) to access the path parts by number:
/// <summary>
/// Return one part of the directory path.
/// Path e.g.: a/b/c/d. PartNr=0 is a, Nr 2 = c.
/// </summary>
/// <param name="Dir"></param>
/// <param name="PartNr"></param>
/// <returns></returns>
public static string DirectoryPart(this DirectoryInfo Dir, int PartNr)
{
string[] Parts = Dir.DirectorySplit().ToArray();
int L = Parts.Length;
return PartNr >= 0 && PartNr < L ? Parts[L - 1 - PartNr] : "";
}
Both above methods are now in my personal library, hence the xml comments. Usage example:
You can still perform additional filters to GetDirectorySegments (since you have an instance of DirectoryInfo you can check atributes or use the Exist property)