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)对于路径更安全
- 有关更复杂的情况,请参见: 及
%PATH%
@mklement0:your's right。令人惊讶的是,八年来,没有人费心去纠正这一点。