using System.Linq; using System.Threading.Tasks; using System.IO; namespace GetFolderSize { class FolderNodes { const int Parallelism = 6; object LockObject = new object(); string BasePathString = ""; int DeepLevel = 0; long TotalFileCount = 0; long TotalFolderCount = 0; long TotalFolderSize = 0; FolderNodes[] SubFolders = null; public string fullPath { get { return BasePathString; } } public string path { get { return Path.GetFileName(BasePathString); } } public FolderNodes[] subFolders { get { return SubFolders; } } public long totalFileCount { get { return TotalFileCount; } } public long totalFolderCount { get { return TotalFolderCount; } } public long totalFolderSize { get { return TotalFolderSize; } } public int deepLevel { get { return DeepLevel; } } public FolderNodes(string path) { if (Directory.Exists(path)) { GetFolderInfo(Path.GetFullPath(path), 0); } else { throw new DirectoryNotFoundException(); } } public FolderNodes(string path, int level) { if (Directory.Exists(path)) { GetFolderInfo(Path.GetFullPath(path), level); } else { throw new DirectoryNotFoundException(); } } private void GetFolderInfo(string path, int level) { ParallelOptions po = new ParallelOptions(); DirectoryInfo di = new DirectoryInfo(path); DirectoryInfo[] dis = di.GetDirectories(); FileInfo[] fis = di.GetFiles(); po.MaxDegreeOfParallelism = Parallelism; BasePathString = di.FullName; DeepLevel = level; TotalFileCount = fis.Length; TotalFolderCount = dis.Length; TotalFolderSize = fis.Sum(item => item.Length); if (dis.Length != 0) { FolderNodes[] folders = new FolderNodes[dis.Length]; int N = folders.Length; Parallel.For(0, N, po, idx => { folders[idx] = new FolderNodes(dis[idx].FullName, level + 1); lock(LockObject) { TotalFileCount += folders[idx].TotalFileCount; TotalFolderCount += folders[idx].TotalFolderCount; TotalFolderSize += folders[idx].TotalFolderSize; } }); SubFolders = folders.OrderByDescending(item => item.TotalFolderSize).ToArray(); } } } }