C# Best way to get folder depth for a given path?

后端 未结 7 2061
野趣味
野趣味 2021-02-19 18:29

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

相关标签:
7条回答
  • 2021-02-19 18:56

    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());
    
    0 讨论(0)
  • 2021-02-19 19:02

    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
    
    • So, for most cases, the best is string.split() (see results in code comments).
    • string.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries) is safer for path.
    • And for more complicated cases see: https://cc.davelozinski.com/c-sharp/fastest-way-count-number-times-character-occurs-string and https://cc.davelozinski.com/c-sharp/c-net-fastest-way-count-substring-occurrences-string
    0 讨论(0)
  • 2021-02-19 19:03

    Off the top of my head:

    Directory.GetFullPath().Split("\\").Length;
    
    0 讨论(0)
  • 2021-02-19 19:10

    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...

    0 讨论(0)
  • 2021-02-19 19:11

    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;
    
    0 讨论(0)
  • 2021-02-19 19:11

    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);

    0 讨论(0)
提交回复
热议问题