C# 获取给定路径的文件夹深度的最佳方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/316009/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# Best way to get folder depth for a given path?
提问by AR.
I'm working on something that requires traversing through the file system and for any given path, I need to know how 'deep' I am in the folder structure. Here's what I'm currently using:
我正在处理需要遍历文件系统和任何给定路径的事情,我需要知道我在文件夹结构中的“深度”。这是我目前正在使用的:
int folderDepth = 0;
string tmpPath = startPath;
while (Directory.GetParent(tmpPath) != null)
{
folderDepth++;
tmpPath = Directory.GetParent(tmpPath).FullName;
}
return folderDepth;
This works but I suspect there's a better/faster way? Much obliged for any feedback.
这有效,但我怀疑有更好/更快的方法吗?非常有义务提供任何反馈。
采纳答案by Paul Sonier
Off the top of my head:
在我的头顶:
Directory.GetFullPath().Split("\").Length;
回答by Jeff Yates
If you use the members of the Path
class, you can cope with localizations of the path separation character and other path-related caveats. The following code provides the depth (including the root). It's not robust to bad strings and such, but it's a start for you.
如果使用Path
类的成员,则可以处理路径分隔字符的本地化和其他与路径相关的警告。以下代码提供深度(包括根)。它对坏字符串之类的东西并不健壮,但它对你来说是一个开始。
int depth = 0;
do
{
path = Path.GetDirectoryName(path);
Console.WriteLine(path);
++depth;
} while (!string.IsNullOrEmpty(path));
Console.WriteLine("Depth = " + depth.ToString());
回答by Jeff Yates
Assuming your path has already been vetted for being valid, in .NET 3.5 you could also use LINQ to do it in 1 line of code...
假设您的路径已经过有效审查,在 .NET 3.5 中,您还可以使用 LINQ 在 1 行代码中完成...
Console.WriteLine(@"C:\Folder1\Folder2\Folder3\Folder4\MyFile.txt".Where(c => c = @"\").Count);
Console.WriteLine(@"C:\Folder1\Folder2\Folder3\Folder4\MyFile.txt".Where(c => c = @"\").Count);
回答by Jeffrey L Whitledge
I'm always a fan the recursive solutions. Inefficient, but fun!
我一直是递归解决方案的粉丝。效率低下,但很有趣!
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;
}
I love the Lisp code written in C#!
我喜欢用 C# 编写的 Lisp 代码!
Here's another recursive version that I like even better, and is probably more efficient:
这是我更喜欢的另一个递归版本,并且可能更有效:
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...
美好的时光,美好的时光……
回答by G?T?
I'm more than late on this but I wanted to point out Paul Sonier's answer is probably the shortest but should be:
我已经迟到了,但我想指出 Paul Sonier 的回答可能是最短的,但应该是:
Path.GetFullPath(tmpPath).Split(Path.DirectorySeparatorChar).Length;
回答by HappyDude
If the directory has a backslash at the end, you get a different answer than when it doesn't. Here's a robust solution to the problem.
如果目录末尾有反斜杠,您会得到与没有反斜杠时不同的答案。这是该问题的强大解决方案。
string pathString = "C:\temp\"
var rootFolderDepth = pathString.Split(Path.DirectorySeparatorChar).Where(i => i.Length > 0).Count();
This returns a path length of 2. If you do it without the where statement, you get a path length of 3 or a path length of 2 if you omit the last separator character.
这将返回 2 的路径长度。如果在没有 where 语句的情况下执行此操作,则如果省略最后一个分隔符,则会得到 3 的路径长度或 2 的路径长度。
回答by Ioan G
Maybe someone need also some performance testing...
也许有人还需要一些性能测试...
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
- So, for most cases, the best is string.split() (see results in code comments).
- string.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries) is safer for path.
- And for more complicated cases see: https://cc.davelozinski.com/c-sharp/fastest-way-count-number-times-character-occurs-stringand https://cc.davelozinski.com/c-sharp/c-net-fastest-way-count-substring-occurrences-string
- 因此,在大多数情况下,最好的是 string.split() (请参阅代码注释中的结果)。
- string.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries) 对路径更安全。
- 对于更复杂的情况,请参阅:https: //cc.davelozinski.com/c-sharp/fastest-way-count-number-times-character-occurs-string和 https://cc.davelozinski.com/c-sharp /c-net-fastest-way-count-substring-occurrences-string