ntsu
ntsu

Reputation: 67

Waiting for a file until it is downloaded using C#

I'm using C# to download different files via url and run them afterwards from a physical filepath in the system, however I need to wait for the file until it is completely written and only then run it. The reason is that some files would need more time than others to be saved and I can't really use Thread.Sleep() for this purpose.

I tried this code but it is not that flexible for some reason, as I can't really tell how many tries or how much time it should be until the file is saved. This depends always on the internet connection as well as on the file size.

   WebClient client = new WebClient();
   var downloadTask = client.DownloadFileTaskAsync(new Uri(url), filepath);
   var checkFile = Task.Run(async () => await downloadTask);
   WaitForFile(filepath, FileMode.CreateNew);

    FileStream WaitForFile(string fullPath, FileMode mode)
    {
        for (int numTries = 0; numTries < 15; numTries++)
        {
            FileStream fs = null;
                try
                {
                    fs = new FileStream(fullPath, mode);
                    return fs;
                }

                catch (IOException)
                {
                    if (fs != null)
                    {
                        fs.Dispose();
                    }
                    Thread.Sleep(50);
                }
        }

        return null;
    }

Is there a way to keep waiting until the File.Length > 0?

I would appreciate any help.

Thanks.

Upvotes: 0

Views: 913

Answers (3)

insane_developer
insane_developer

Reputation: 819

I think this is all you have to do:

WebClient client = new WebClient();
 await client.DownloadFileTaskAsync(new Uri(url), filepath);
 // code continues when the file finishes downloading

Upvotes: 0

Alejandro
Alejandro

Reputation: 7811

You're not awaiting for the file to complete download. Or better said, you're awaiting, in a different thread, and then throwing that result away. Just wait in the very same method and you no longer need a separate way to know when the file is downloaded

WebClient client = new WebClient();
await client.DownloadFileTaskAsync(new Uri(url), filepath);

Upvotes: 2

Adassko
Adassko

Reputation: 5343

You can use FileSystemWatcher to get an event when file changes its size or a new file appear https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher.onchanged?view=netcore-3.1

But you can't really tell if the file is fully downloaded this way unless you know its size.

You should just change the code that downloads the file so that it notifies when the file is downloaded.

Upvotes: 0

Related Questions