C# - Loop no while

Asked

Viewed 80 times

1

I have a C# function that checks if a download has been completed by referring to whether the file exists .crdownload is true.

If this does not exist, I assign a true boolean to the while variable, and theoretically I should close this loop. But it does not happen.

private bool CheckDownloadByPartialName_v2(string partialName, string path)
{
    bool success = false;
    DirectoryInfo directory = new DirectoryInfo(path);

    while (!success)
    {
        bool downloading = directory.GetFiles()
                                  .Where(file => file.Name.StartsWith(partialName))
                                  .Where(file => file.Extension == ".crdownload")
                                  .SingleOrDefault()
                                  .Exists;

        if (!downloading)
            success = true;
    }

    return success;
}

Another problem I’m facing in this code is that when the file extension .crdownload there is no (end of loop) my code from an Exception (Object Reference not set to an instance of an Object.)

Probably caused by the .SingleOrDefault() of my LINQ query.

Someone can help me with these things?

  • 3

    It is absurd to do this, it will detonate the processor and disk for nothing, you have to use https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=netframework-4.8.

  • I am aware that this can use a lot of processing, but it is just a small robot that visits the control panel of my VPN and downloads the access logs to an external directory.

  • I can’t understand why the loop repeats after declaring the variable sucess as true

2 answers

1


The problem is that the expression LINQ does not make sense. You are consulting items that exist in a directory and then using the Exists to validate if the item exists (but the query has already done this job).

So when there is no one with the extension crdownload the return SingleOrDefault will be null and so the exception happens.

You simplify the expression for this below:

var downloading = directory.GetFiles().Any(f => f.Name.StartsWith(partialName) &&
                                                f.Extension == ".crdownload");

Note that, as already noted in the comments, this is a gigantic nonsense. There are . NET API’s ready and optimized for this type of work.

1

Comments are right your code makes no sense, don’t take it badly.

using System.Data;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;

namespace Tools
{
    public static class DownloadChecker
    {
        public static bool CheckDownloadByPartialName_v2(string partialName, string path)
        {
            // Use uma expressão regular:
            Regex regex = new Regex($"{partialName}.*");

            bool complete;

            for (; ; )
            {
                //Verifique se existe algum arquivo que corresponde à expressão:
                complete = Directory.GetFiles(path, "*.crdownload").Where(file => regex.IsMatch(Path.GetFileName(file))).Count() == 0;

                if (complete)
                    return complete;

                // Espere um pouco para não colocar seu processador em 100%:
                Thread.Sleep(50);
            }
        }
    }
}

Use:

var complete = Tools.DownloadChecker.CheckDownloadByPartialName_v2("nome parcial", @"c:\caminho\do\arquivo");

Remembering that maybe this is not the best way to do this, as it blocks the current Thread, use a Task if possible.

And with a basic knowledge in regular expressions can modify the expression to your need. What if the partialName contain characters reserved for regular expression will need to escape them.

If you know the exact file name becomes easier with:

File.Exists("arquivo");

The comment of Maniero is very valid, it can be a better option, therefore you decrease the number of queries in the file system.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.