I\'m working on something that requires traversing through the file system and for any given path, I need to know how \'deep\' I am in the folder structure. Here\'s what I\'m cu
If you use the members of the Path
class, you can cope with localizations of the path separation character and other path-related caveats. The following code provides the depth (including the root). It's not robust to bad strings and such, but it's a start for you.
int depth = 0;
do
{
path = Path.GetDirectoryName(path);
Console.WriteLine(path);
++depth;
} while (!string.IsNullOrEmpty(path));
Console.WriteLine("Depth = " + depth.ToString());
Maybe someone need also some performance testing...
double linqCountTime = 0;
double stringSplitTime = 0;
double stringSplitRemEmptyTime = 0;
int linqCountFind = 0;
int stringSplitFind = 0;
int stringSplitRemEmptyFind = 0;
string pth = @"D:\dir 1\complicated dir 2\more complicated dir 3\much more complicated dir 4\only dir\another complicated dir\dummy\dummy.dummy.45682\";
//Heat Up
DateTime dt = DateTime.Now;
for (int i = 0; i < 10000; i++)
{
linqCountFind = pth.Count(c => c == '\\');
}
_= DateTime.Now.Subtract(dt).TotalMilliseconds;
dt = DateTime.Now;
for (int i = 0; i < 10000; i++)
{
stringSplitFind = pth.Split('\\').Length;
}
_ = DateTime.Now.Subtract(dt).TotalMilliseconds;
dt = DateTime.Now;
for (int i = 0; i < 10000; i++)
{
stringSplitRemEmptyFind = pth.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Length;
}
_ = DateTime.Now.Subtract(dt).TotalMilliseconds;
dt = DateTime.Now;
//Testing
dt = DateTime.Now;
for (int i = 0; i < 1000000; i++)
{
linqCountFind = pth.Count(c => c == '\\');
}
linqCountTime = DateTime.Now.Subtract(dt).TotalMilliseconds; //linq.Count: 1390 ms
dt = DateTime.Now;
for (int i = 0; i < 1000000; i++)
{
stringSplitFind = pth.Split('\\').Length-1;
}
stringSplitTime = DateTime.Now.Subtract(dt).TotalMilliseconds; //string.Split: 715 ms
dt = DateTime.Now;
for (int i = 0; i < 1000000; i++)
{
stringSplitRemEmptyFind = pth.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Length;
}
stringSplitRemEmptyTime = DateTime.Now.Subtract(dt).TotalMilliseconds; // string.Split with RemoveEmptyEntries option: 720 ms
string linqCount = "linqCount - Find: "+ linqCountFind + "; Time: "+ linqCountTime.ToString("F0") +" ms"+ Environment.NewLine;
string stringSplit = "stringSplit - Find: " + stringSplitFind + "; Time: " + stringSplitTime.ToString("F0") + " ms" + Environment.NewLine;
string stringSplitRemEmpty = "stringSplitRemEmpty - Find: " + stringSplitRemEmptyFind + "; Time: " + stringSplitRemEmptyTime.ToString("F0") + " ms" + Environment.NewLine;
MessageBox.Show(linqCount + stringSplit + stringSplitRemEmpty);
// Results:
// linqCount - Find: 9; Time: 1390 ms
// stringSplit - Find: 9; Time: 715 ms
// stringSplitRemEmpty - Find: 9; Time: 720 ms
Off the top of my head:
Directory.GetFullPath().Split("\\").Length;
I'm always a fan the recursive solutions. Inefficient, but fun!
public static int FolderDepth(string path)
{
if (string.IsNullOrEmpty(path))
return 0;
DirectoryInfo parent = Directory.GetParent(path);
if (parent == null)
return 1;
return FolderDepth(parent.FullName) + 1;
}
I love the Lisp code written in C#!
Here's another recursive version that I like even better, and is probably more efficient:
public static int FolderDepth(string path)
{
if (string.IsNullOrEmpty(path))
return 0;
return FolderDepth(new DirectoryInfo(path));
}
public static int FolderDepth(DirectoryInfo directory)
{
if (directory == null)
return 0;
return FolderDepth(directory.Parent) + 1;
}
Good times, good times...
I'm more than late on this but I wanted to point out Paul Sonier's answer is probably the shortest but should be:
Path.GetFullPath(tmpPath).Split(Path.DirectorySeparatorChar).Length;
Assuming your path has already been vetted for being valid, in .NET 3.5 you could also use LINQ to do it in 1 line of code...
Console.WriteLine(@"C:\Folder1\Folder2\Folder3\Folder4\MyFile.txt".Where(c => c = @"\").Count);