Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#获取给定路径的文件夹深度的最佳方法?_C#_.net_Directory - Fatal编程技术网

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

C#获取给定路径的文件夹深度的最佳方法?,c#,.net,directory,C#,.net,Directory,我正在做一些需要遍历文件系统的工作,对于任何给定的路径,我需要知道我在文件夹结构中的“深度”。以下是我目前正在使用的内容: int folderDepth = 0; string tmpPath = startPath; while (Directory.GetParent(tmpPath) != null) { folderDepth++; tmpPath = Directory.GetParent(tmpPath).FullName; } return folderDep

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

int folderDepth = 0;
string tmpPath = startPath;

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

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

在我的脑海中:

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

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

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

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

假设您的路径已经过有效的审查,在.NET3.5中,您还可以使用LINQ在一行代码中完成它

Console.WriteLine(@“C:\Folder1\Folder2\Folder3\Folder4\MyFile.txt”。其中(C =>c=@“\”.Count)


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

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

好时光,好时光…

我在这方面已经晚了很多,但我想指出保罗·索尼埃的答案可能是最短的,但应该是:

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

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

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

这将返回2的路径长度。如果不使用where语句,则如果省略最后一个分隔符,则路径长度为3或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
double linqCountTime=0;
双线分裂时间=0;
双线分隔时间=0;
int-linqCountFind=0;
int-stringSplitFind=0;
int stringSplitRemEmptyFind=0;
字符串pth=@“D:\dir 1\complexed dir 2\more complexed dir 3\more complexed dir 4\only dir\other complexed dir\dummy\dummy.45682\”;
//加热
DateTime dt=DateTime.Now;
对于(int i=0;i<10000;i++)
{
linqCountFind=pth.Count(c=>c=='\\');
}
_=DateTime.Now.Subtract(dt).total毫秒;
dt=日期时间。现在;
对于(int i=0;i<10000;i++)
{
stringSplitFind=pth.Split('\\').Length;
}
_=DateTime.Now.Subtract(dt).total毫秒;
dt=日期时间。现在;
对于(int i=0;i<10000;i++)
{
stringSplitRemEmptyFind=pth.Split(新字符[]{'\\'},StringSplitOptions.RemoveEmptyEntries);
}
_=DateTime.Now.Subtract(dt).total毫秒;
dt=日期时间。现在;
//测试
dt=日期时间。现在;
对于(int i=0;i<1000000;i++)
{
linqCountFind=pth.Count(c=>c=='\\');
}
linqCountTime=DateTime.Now.Subtract(dt).total毫秒//林克计数:1390毫秒
dt=日期时间。现在;
对于(int i=0;i<1000000;i++)
{
stringSplitFind=pth.Split(“\\”).Length-1;
}
stringSplitTime=DateTime.Now.Subtract(dt).TotalMillistics//字符串。拆分:715毫秒
dt=日期时间。现在;
对于(int i=0;i<1000000;i++)
{
stringSplitRemEmptyFind=pth.Split(新字符[]{'\\'},StringSplitOptions.RemoveEmptyEntries);
}
stringSplitRemEmptyTime=DateTime.Now.Subtract(dt).TotalMillistics;//字符串。使用RemoveEmptyEntries选项拆分:720毫秒
字符串linqCount=“linqCount-Find:”+linqCountFind+“Time:”+linqCountTime.ToString(“F0”)+“ms”+Environment.NewLine;
string stringSplit=“stringSplit-Find:”+stringSplitFind+“Time:”+stringSplitTime.ToString(“F0”)+“ms”+Environment.NewLine;
stringSplitRemEmpty=“stringSplitRemEmpty-Find:”+stringSplitRemEmptyFind+”;时间:“+stringSplitRemEmptyTime.ToString(“F0”)+“ms”+Environment.NewLine;
Show(linqCount+stringSplit+stringSplitRemEmpty);
//结果:
//林克计数-发现:9;时间:1390毫秒
//stringSplit-Find:9;时间:715毫秒
//stringSplitRemEmpty-Find:9;时间:720毫秒
  • 因此,对于大多数情况,最好的方法是string.split()(请参见代码注释中的结果)
  • string.Split(新字符[]{'\'},StringSplitOptions.RemoveEmptyEntries)对于路径更安全
  • 有关更复杂的情况,请参见: 及

非常喜欢这个想法!请注意,长度是一个属性而不是一个方法。对于其他有效序列,例如C:\Folder\..\boot.ini,长度将被破坏。或者,对于UNC网络路径,如\\server\share\file。而且,你可能应该使用Path.directoryseparatorcharacter和Path.altdirectoryseparatorcharacter.AR:你仍然可以使用System.IO.Path.pathseptor而不是\@Joey:我想你是说。有些令人困惑的是,它指的是环境变量中路径之间的分隔符,例如
%PATH%
@mklement0:your's right。令人惊讶的是,八年来,没有人费心去纠正这一点。