diff --git a/app/MindWork AI Studio/Tools/DirectoryInfoExtensions.cs b/app/MindWork AI Studio/Tools/DirectoryInfoExtensions.cs new file mode 100644 index 0000000..87564ae --- /dev/null +++ b/app/MindWork AI Studio/Tools/DirectoryInfoExtensions.cs @@ -0,0 +1,62 @@ +namespace AIStudio.Tools; + +public static class DirectoryInfoExtensions +{ + private static readonly EnumerationOptions ENUMERATION_OPTIONS = new() + { + IgnoreInaccessible = true, + RecurseSubdirectories = true, + ReturnSpecialDirectories = false, + }; + + /// + /// Determines the size of the directory and all its subdirectories, as well as the number of files. When desired, + /// it can report the found files up to a certain limit. + /// + /// + /// You might set reportMaxFiles to a negative value to report all files. Any positive value will limit the number + /// of reported files. The cancellation token can be used to stop the operation. The cancellation operation is also able + /// to cancel slow operations, e.g., when the directory is on a slow network drive. + /// + /// After stopping the operation, the total size and number of files are reported as they were at the time of cancellation. + /// + /// Please note that the entire operation is done on a background thread. Thus, when reporting the found files or the + /// current total size, you need to use the appropriate dispatcher to update the UI. Usually, you can use the InvokeAsync + /// method to update the UI from a background thread. + /// + /// + /// + /// + /// + /// + /// + public static async Task DetermineContentSize(this DirectoryInfo directoryInfo, Action reportCurrentTotalSize, Action reportCurrentNumFiles, Action reportNextFile, int reportMaxFiles = -1, CancellationToken cancellationToken = default) + { + var rootDirectoryLen = directoryInfo.FullName.Length; + long totalSize = 0; + long numFiles = 0; + + await Task.Factory.StartNew(() => { + foreach (var file in directoryInfo.EnumerateFiles("*", ENUMERATION_OPTIONS)) + { + if (cancellationToken.IsCancellationRequested) + return; + + totalSize += file.Length; + numFiles++; + + if (numFiles % 100 == 0) + { + reportCurrentTotalSize(totalSize); + reportCurrentNumFiles(numFiles); + } + + if (reportMaxFiles < 0 || numFiles <= reportMaxFiles) + reportNextFile(file.FullName[rootDirectoryLen..]); + } + }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Default); + + reportCurrentTotalSize(totalSize); + reportCurrentNumFiles(numFiles); + } +} \ No newline at end of file