File search method:

private List<string> GetFilesList(string path, string pattern) { List<string> fileList = new List<string>(); foreach (string fileName in Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)) { if (pattern.Contains(Path.GetExtension(fileName))) { fileList.Add(fileName); } } return fileList; } 

Folder check method:

 static long GetDirSize(string path) { long size = 0; string[] files = Directory.GetFiles(path); foreach (string file in files) size += (new FileInfo(file)).Length; string[] dirs = Directory.GetDirectories(path); foreach (string dir in dirs) size += GetDirSize(dir); return size; } 

Now I do a check:

 if (GetDirSize(TxtPath) < 1000000) { // Если папка превышает размер: остановить метод GetFilesList(path,pattern); } else // Если не превышает продолжить метод пока папка не будет превышать заданный размер. 

The trouble is that I can't do everything together (using a while(true) , or on a timer.

PS: The point is to make a check, and stop the called method after exceeding the folder size.

PPS: I put the question in a slightly different form: When calling the method GetFilesList(path,pattern); - Files are copied into my folder (all files), it takes a long time and weight! Therefore, you need to check the size of the folder, and stop the execution of the function of the method).

  • I understand correctly that you want to run a check ( GetDirSize ) and get a list of files ( GetFilesList ) in parallel? And if the test is not worked out, then stop the process of obtaining a list of files. - Vlad
  • @Vlad, Yes, exactly! - GooliveR

4 answers 4

It depends on which folders you are processing, if “folders in general”, then this is quite a standard situation in which folders will exceed the size you need, then something like this:

 private int GetFilesList(string path, string pattern, out List<string> fileList) { int result = 1; fileList = new List<string>(); if (GetDirSize(path) < 1000000) { result = 0; foreach (string fileName in Directory.GetFiles( path , "*.*" , SearchOption.AllDirectories)) { if (pattern.Contains(Path.GetExtension(fileName))) { fileList.Add(fileName); } } } return result; } 

And accordingly process the codes returned by the function.

If these are quite specific folders that are “obliged” to have a certain size, then in the presence of an exceptional situation, it is better to work with it through exceptions.

 public class DirSiztException : Exception { public DirSiztException() { } public DirSiztException(string message) : base(message) { } public DirSiztException(string message, Exception inner) : base(message, inner) { } protected DirSiztException(SerializationInfo info, StreamingContext context) : base(info, context) { } } private List<string> GetFilesList(string path, string pattern) { if (GetDirSize(path) > 1000000) throw DirSizeExeption("Directory {0} size is too mach", path); List<string> fileList = new List<string>(); foreach (string fileName in Directory.GetFiles(path, "*.*", SearchOption.AllDirectories)) { if (pattern.Contains(Path.GetExtension(fileName))) { fileList.Add(fileName); } } return fileList; } 
  • in your example in 1 post, in return result causes an error: Ошибка 1 До передачи управления из текущего метода параметру, помеченному ключевым словом out, "fileList" должно быть присвоено значение - GooliveR
  • @ArteS Sub-corrected, transfer assignment from ifa. - Mirdin
  • And when you call GetFilesList(path,pattern,что здесь требуется?); - GooliveR
  • @ArteS, it requires some sort of list to return values. you called it before: List<string> files = GetFileList(..) , and now like this; List<string> files; if (GetFileList(... , files) == 0) { какие то действия foreach (var f is files) {} //например } List<string> files; if (GetFileList(... , files) == 0) { какие то действия foreach (var f is files) {} //например } - Mirdin
  • First, SearchOption.AllDirectories is evil - if you exclude, there will be problems, and secondly, you already have a full array in memory. - Qwertiy

These methods should be combined and returned to IEnumerable<Tuple<String, long>> , where in the first element is the file name, and in the second is the total size. Accordingly, by checking the size, you can find out that the desired limit has been reached and finish there.

  • If not difficult to give an example) - GooliveR

I will offer this option.

Add the CancellationToken t parameter to the GetFilesList method. Inside the foreach call t.ThrowIfCancellationRequested() .

After that we try to collect everything in a heap.

 static async Task GetFiles() { // перечень файлов List<string> filesList = null; var tokenSource = new CancellationTokenSource(); // запускаем задачу по отмене операции. Если размер директории слишком большой - вызываем `Cancel` у `CancellationTokenSource`. var cancellationTask = Task.Run(() => { if (GetDirSize("") > 1000000) { tokenSource.Cancel(); } }); try { // запускаем операцию и ожидаем ее результатов filesList = await Task.Run(() => GetFilesList("", "", tokenSource.Token)); // если задача по высчитыванию необходимости завершения еще не завершилась, то дожидаемся ее await cancellationTask; // бросаем OperationCanceledException, если запрос на отмену был произведен // этот метод бросит исключение в том случае, если cancellationTask отменила выполнения, но длилась дольше, чем задача получения перечня файлов tokenSource.Token.ThrowIfCancellationRequested(); } catch (OperationCanceledException) { // операция отменена } catch (Exception e) { // что-то пошло не так } } 
  • @ArteS And here Linq ? - Vlad
  • A. Well, for .Net 2.0 , of course, this solution does not work. - Vlad
  • I switched to the example of Linq, can I clarify a couple of details? How to call and finish ?! (or does it end when a large number of files in the folder is reached (and during the check it stops if the weight has reached the desired size)?)) - GooliveR
  • one
    @ArteS, call - await GetFiles (). The method will end on its own: either with cancellation, if the number of files in the folder is exceeded, or successfully. - Vlad
  • confused a bit, in the line: GetFilesList("", "", tokenSource.Token)); empty brackets are for (path, file format, token)); ? - GooliveR

Use return for example

 return null; 

or

 return new List<string>(); 

or

 return fileList; 
  • quite a bad decision, because it is not informative: there are no files in the folder, or an error has occurred, and if there is an error, which one. Such a program will be very difficult to debug, and logging is also not fun to set up. - Mirdin
  • one
    if an error occurs, it should be wrapped in a try catch. or impose checks and throw out exception every time. As I understand it in this case, the author did not want to throw out the exception, but only did not execute further method code. - user2455111