Hierarchy of files and directories in C #, can you do both?

This may be a confusing question, but I wrote below the Directory crawler, which starts with the root crawler, finds all the unique directories, then finds all the files and counts them and adds their file size. However, the way I wrote it requires you to go to the directory twice, one is to find directories and next time count the files. If / how can I get all the information once?

Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); HashSet<string> DirectoryHolding = new HashSet<string>(); DirectoryHolding.Add(rootDirectory); #region All Directory Region int DirectoryCount = 0; int DirectoryHop = 0; bool FindAllDirectoriesbool = true; while (FindAllDirectoriesbool == true) { string[] DirectoryHolder = Directory.GetDirectories(rootDirectory); if (DirectoryHolder.Length == 0) { if (DirectoryHop >= DirectoryHolding.Count()) { FindAllDirectoriesbool = false; } else { rootDirectory = DirectoryHolding.ElementAt(DirectoryHop); } DirectoryHop++; } else { foreach (string DH in DirectoryHolder) { DirectoryHolding.Add(DH); } if (DirectoryHop > DirectoryHolding.Count()) { FindAllDirectoriesbool = false; } rootDirectory = DirectoryHolding.ElementAt(DirectoryHop); DirectoryHop++; } } DirectoryCount = DirectoryHop - 2; #endregion #region File Count and Size Region int FileCount = 0; long FileSize = 0; for (int i = 0; i < DirectoryHolding.Count ; i++) { string[] DirectoryInfo = Directory.GetFiles(DirectoryHolding.ElementAt(i)); for (int fi = 0; fi < DirectoryInfo.Length; fi++) { try { FileInfo fInfo = new FileInfo(DirectoryInfo[fi]); FileCount++; FileSize = FileSize + fInfo.Length; } catch (Exception ex) { Console.WriteLine(ex.Message.ToString()); } } } 

The stopwatch result for this is 1.38

 int FileCount = 0; long FileSize = 0; for (int i = 0; i < DirectoryHolding.Count; i++) { var entries = new DirectoryInfo(DirectoryHolding.ElementAt(i)).EnumerateFileSystemInfos(); foreach (var entry in entries) { if ((entry.Attributes & FileAttributes.Directory) == FileAttributes.Directory) { DirectoryHolding.Add(entry.FullName); } else { FileCount++; FileSize = FileSize + new FileInfo(entry.FullName).Length; } } } 

the stopwatch for this method is 2.01,

it makes no sense to me.

  DirectoryInfo Dinfo = new DirectoryInfo(rootDirectory); DirectoryInfo[] directories = Dinfo.GetDirectories("*.*", SearchOption.AllDirectories); FileInfo[] finfo = Dinfo.GetFiles("*.*", SearchOption.AllDirectories); foreach (FileInfo f in finfo) { FileSize = FileSize + f.Length; } FileCount = finfo.Length; DirectoryCount = directories.Length; 

.26 seconds, I think it is a winner

+4
source share
2 answers

You can use Directory.EnumerateFileSystemEntries() :

 var entries = Directory.EnumerateFileSystemEntries(rootDirectory); foreach (var entry in entries) { if(File.Exists(entry)) { //file } else { //directory } } 

Or, alternatively, DirectoryInfo.EnumerateFileSystemInfos() (this may be more efficient, since FileSystemInfo already has most of the necessary information, and you can skip checking File.Exists ):

 var entries = new DirectoryInfo(rootDirectory).EnumerateFileSystemInfos(); foreach (var entry in entries) { if ((entry.Attributes & FileAttributes.Directory) == FileAttributes.Directory) { //direcotry } else { //file } } 
+7
source

The usual approach is to write a recursive method. Here it is in pseudocode:

 void ProcessDirectory(Dir directory) { foreach (var file in directory.Files) ProcessFile(file); foreach (var child in directory.Subdirectories) ProcessDirectory(directory); } 

You can also reorder foreach loops. For example, to calculate the total size of all files using a recursive method, you can do this:

 int GetTotalFileSize(Dir directory) { ulong result = 0UL; foreach (var child in directory.Subdirectories) result += GetTotalFileSize(directory); foreach (var file in directory.Files) result += file.Length; return result; } 
+2
source

Source: https://habr.com/ru/post/1403974/


All Articles