【问题标题】:C# Best way to get folder depth for a given path?C#获取给定路径的文件夹深度的最佳方法?
【发布时间】:2010-09-23 21:07:34
【问题描述】:

我正在做一些需要遍历文件系统的事情,对于任何给定的路径,我需要知道我在文件夹结构中的“深度”。这是我目前正在使用的:

int folderDepth = 0;
string tmpPath = startPath;

while (Directory.GetParent(tmpPath) != null) 
{
    folderDepth++;
    tmpPath = Directory.GetParent(tmpPath).FullName;
}
return folderDepth;

这可行,但我怀疑有更好/更快的方法吗?非常感谢任何反馈。

【问题讨论】:

    标签: c# .net directory


    【解决方案1】:

    在我的头顶:

    Directory.GetFullPath().Split("\\").Length;
    

    【讨论】:

    • 非常喜欢这个主意!只是一个简短的说明,长度是一个属性而不是一个方法。
    • 对于其他有效序列(例如 C:\Folder\..\boot.ini)将被破坏。或者,对于 UNC 网络路径,例如 \\server\share\file。而且,您可能应该使用 Path.DirectorySeperatorCharacter 和 Path.AltDirectorySeperatorCharacter。
    • AR:您仍然可以使用 System.IO.Path.PathSeparator 代替 \
    • @Joey:我想你的意思是System.IO.Path.DirectorySeparatorChar。有点令人困惑的是,System.IO.Path.PathSeparator 指的是环境变量中的分隔符 between 路径,例如%PATH%
    • @mklement0:你是对的。令人惊讶的是,八年来没有人愿意纠正这一点。
    【解决方案2】:

    我已经迟到了,但我想指出 Paul Sonier 的回答可能是最短的,但应该是:

     Path.GetFullPath(tmpPath).Split(Path.DirectorySeparatorChar).Length;
    

    【讨论】:

      【解决方案3】:

      我一直是递归解决方案的粉丝。效率低下,但很有趣!

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

      我喜欢用 C# 编写的 Lisp 代码!

      这是另一个我更喜欢的递归版本,并且可能更高效:

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

      好时光,好时光……

      【讨论】:

        【解决方案4】:

        如果您使用Path 类的成员,您可以处理路径分隔字符的本地化和其他与路径相关的警告。以下代码提供深度(包括根)。它对坏字符串等并不健壮,但它对你来说是一个开始。

        int depth = 0;
        do
        {
            path = Path.GetDirectoryName(path);
            Console.WriteLine(path);
            ++depth;
        } while (!string.IsNullOrEmpty(path));
        
        Console.WriteLine("Depth = " + depth.ToString());
        

        【讨论】:

          【解决方案5】:

          假设您的路径已经过有效验证,在 .NET 3.5 中,您还可以使用 LINQ 在 1 行代码中执行此操作...

          Console.WriteLine(@"C:\Folder1\Folder2\Folder3\Folder4\MyFile.txt".Where(c => c = @"\").Count);

          【讨论】:

            【解决方案6】:

            如果目录末尾有反斜杠,您会得到与没有反斜杠时不同的答案。这是该问题的可靠解决方案。

            string pathString = "C:\\temp\\"
            var rootFolderDepth = pathString.Split(Path.DirectorySeparatorChar).Where(i => i.Length > 0).Count();
            

            这将返回路径长度 2。如果不使用 where 语句,则路径长度为 3,如果省略最后一个分隔符,则路径长度为 2。

            【讨论】:

              【解决方案7】:

              也许有人还需要一些性能测试...

                      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
              

              【讨论】:

                猜你喜欢
                • 2011-08-27
                • 1970-01-01
                • 2016-12-12
                • 2019-02-08
                • 2023-04-02
                • 1970-01-01
                • 1970-01-01
                • 2017-06-03
                • 2013-07-05
                相关资源
                最近更新 更多