我正在研究需要遍历文件系统的东西,对于任何给定的路径,我需要知道我在文件夹结构中的“深度”。这是我目前正在使用的:
int folderDepth = 0;
string tmpPath = startPath;
while (Directory.GetParent(tmpPath) != null)
{
folderDepth++;
tmpPath = Directory.GetParent(tmpPath).FullName;
}
return folderDepth;
这有效但我怀疑有更好/更快的方式吗?很有必要提供任何反馈。
答案 0 :(得分:12)
脱离我的头顶:
Directory.GetFullPath().Split("\\").Length;
答案 1 :(得分:7)
我比这更晚了,但我想指出Paul Sonier的回答可能是最短的,但应该是:
Path.GetFullPath(tmpPath).Split(Path.DirectorySeparatorChar).Length;
答案 2 :(得分:4)
我一直是递归解决方案的粉丝。效率低下,但很有趣!
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;
}
美好时光,美好时光......
答案 3 :(得分:3)
假设您的路径已经过有效审查,在.NET 3.5中您还可以使用LINQ在一行代码中执行此操作...
Console.WriteLine(@ “C:\ Folder1中\ FOLDER2 \ Folder3 \ Folder4 \ MyFile.txt的”。凡(三 => c = @“\”)。计数);
答案 4 :(得分:1)
如果您使用Path
类的成员,则可以处理路径分离字符的本地化以及其他与路径相关的警告。以下代码提供深度(包括根)。对于糟糕的字符串而言,它并不健壮,但这对你来说是一个开始。
int depth = 0;
do
{
path = Path.GetDirectoryName(path);
Console.WriteLine(path);
++depth;
} while (!string.IsNullOrEmpty(path));
Console.WriteLine("Depth = " + depth.ToString());
答案 5 :(得分:0)
如果目录末尾有反斜杠,则得到的答案与没有反斜杠的答案不同。这是解决问题的可靠方法。
string pathString = "C:\\temp\\"
var rootFolderDepth = pathString.Split(Path.DirectorySeparatorChar).Where(i => i.Length > 0).Count();
这将返回路径长度2。如果不使用where语句,则会得到3的路径长度,或者如果省略最后一个分隔符,则会得到2的路径长度。
答案 6 :(得分:-1)
也许有人还需要一些性能测试...
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