获取最大目录深度
本文关键字:深度 获取 | 更新日期: 2023-09-27 18:37:17
我只是想知道,是否有一种快速的解决方案可以获取根目录中最深文件夹的级别。
假设我使用"C:''"然后我需要一个函数,它可以让我获得根目录中"最深"文件夹的级别数,而无需遍历每个目录。
最好的办法是递归地使用 System.IO.DirectoryInfo GetDirectories
。确保不要使用SearchOption.AllDirectories
因为那样会肯定会因安全错误而中断!
static List<string> directories = new List<string>();
static void GetDirectories(string path)
{
try
{
foreach (var directory in Directory.GetDirectories(path))
{
var di = new DirectoryInfo(directory);
directories.Add(di.FullName);
GetDirectories(di.FullName);
}
}
catch (UnauthorizedAccessException uaex) { }
catch (PathTooLongException ptlex) { }
catch (Exception ex) { }
}
static void Main(string[] args)
{
var path = @"C:'";
GetDirectories(path);
var maxLevel = directories.Max(d => d.Split('''').Count());
var deepest = directories.Select(d => new
{
Path = d,
Levels = d.Split('''').Count()
})
.OrderByDescending(d => d.Levels)
.First();
}
但是你会遇到一个PathTooLongException
,看看这个问题如何解决这个问题。
我对PathTooLongException
感到困扰,并提出了这个:
public static class DirectoryEx
{
static char driveLetter;
static string longPath;
static List<string> directories;
static DirectoryEx()
{
longPath = String.Empty;
}
private static char GetAvailableDrive()
{
var all = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray().Reverse();
var occupied = DriveInfo.GetDrives()
.OrderByDescending(d => d.Name)
.Select(d => (char)d.Name.ToUpper().First());
var free = all.Except(occupied).First();
return free;
}
public static List<string> GetDirectories(string path)
{
directories = new List<string>();
// recursive call
FindDirectories(path);
return directories;
}
static void FindDirectories(string path)
{
try
{
foreach (var directory in Directory.GetDirectories(path))
{
var di = new DirectoryInfo(directory);
if(!String.IsNullOrEmpty(longPath))
directories.Add(di.FullName.Replace(driveLetter + ":''", longPath + "''"));
else
directories.Add(di.FullName);
FindDirectories(di.FullName);
}
}
catch (UnauthorizedAccessException uaex) { Debug.WriteLine(uaex.Message); }
catch (PathTooLongException ptlex)
{
Debug.WriteLine(ptlex.Message);
longPath = path;
Task t = new Task(new Action(() =>
{
CreateVirtualDrive(longPath);
FindDirectories(driveLetter + ":''");
DeleteVirtualDrive();
longPath = String.Empty;
}));
if (!String.IsNullOrEmpty(longPath))
t.RunSynchronously();
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
static void CreateVirtualDrive(string path)
{
driveLetter = GetAvailableDrive();
Process.Start(new ProcessStartInfo() {
FileName = "cmd.exe",
WindowStyle = ProcessWindowStyle.Hidden,
Arguments = String.Format("/c subst {0}: {1}", driveLetter.ToString(), path)
});
while (!DriveInfo.GetDrives().Select(d => d.Name.ToUpper().First()).Contains(driveLetter))
{
System.Threading.Thread.Sleep(1);
}
}
static void DeleteVirtualDrive()
{
Process.Start(new ProcessStartInfo()
{
FileName = "cmd.exe",
WindowStyle = ProcessWindowStyle.Hidden,
Arguments = String.Format("/c subst {0}: /D", driveLetter.ToString())
});
while (DriveInfo.GetDrives().Select(d => d.Name.ToUpper().First()).Contains(driveLetter))
{
System.Threading.Thread.Sleep(1);
}
}
}
用作var directories = DirectoryEx.GetDirectories("C:''");
这将为每个太长的路径创建一个虚拟驱动器(使用 SUBST
),以便它仍然可以遍历它。需要优化,可以扩展以提供一些DirectoryInfo
包装类。