C#获取给定路径的文件夹深度的最佳方法是什么?

13

我正在处理需要遍历文件系统的内容,对于任何给定的路径,我需要知道我在文件夹结构中有多深。这是我目前正在使用的代码:

int folderDepth = 0;
string tmpPath = startPath;

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

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

7个回答

12

凭借我的记忆:

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

6
否则,对于像C:\Folder.. \boot.ini这样有效的序列或UNC网络路径(例如\server\share\file),它们将被破坏。而且,你应该使用Path.DirectorySeperatorCharacter和Path.AltDirectorySeperatorCharacter。 - Mark Brackett
1
AR: 你仍然可以使用 System.IO.Path.PathSeparator 而不是 \。 - Joey
1
在反斜杠字符周围应该使用单引号:Directory.GetFullPath().Split('\').Length; - Mehdi LAMRANI
2
@Joey:我认为你指的是System.IO.Path.DirectorySeparatorChar。有点令人困惑的是,System.IO.Path.PathSeparator 是指环境变量(如%PATH%)中路径之间的分隔符。 - mklement0
3
@mklement0:你说得对。令人惊讶的是,在八年时间里,竟然没有人注意到这个错误并进行更正。 - Joey
显示剩余2条评论

10

我可能晚了,但是我想指出Paul Sonier的答案可能是最短的,应该是:

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

如果您需要C:\WindowsC:\Windows\返回相同的深度值,则可以使用Path.GetFullPath(tmpPath).Split(Path.DirectorySeparatorChar,System.StringSplitOptions.RemoveEmptyEntries).Length; - Bacon Bits

5

我总是喜欢递归解决方案。虽然效率低下,但很有趣!

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

Good times, good times...


4
如果您使用Path类的成员,您可以处理路径分隔符和其他与路径相关的注意事项。以下代码提供了深度(包括根目录)。它并不稳健,无法应对错误的字符串等问题,但这是一个起点。
int depth = 0;
do
{
    path = Path.GetDirectoryName(path);
    Console.WriteLine(path);
    ++depth;
} while (!string.IsNullOrEmpty(path));

Console.WriteLine("Depth = " + depth.ToString());

1
假设您的路径已经通过验证为有效,在.NET 3.5中,您还可以使用LINQ在一行代码中完成它...

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


-1
如果目录末尾有反斜杠,与没有反斜杠时会得到不同的答案。这里提供了一个强大的解决方案来解决这个问题。
string pathString = "C:\\temp\\"
var rootFolderDepth = pathString.Split(Path.DirectorySeparatorChar).Where(i => i.Length > 0).Count();

这将返回路径长度为2。如果没有where语句,您将得到路径长度为3或者如果省略最后一个分隔符字符,则路径长度为2。


-2

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

        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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接