WebClient
DownloadFileAsync
file overwrite
C#
.NET

Does WebClient.DownloadFileAsync overwrite the file if it already exists on disk?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Yes. WebClient.DownloadFileAsync writes to the destination path you provide, and if that file already exists, it is overwritten as long as the process has permission to write there. The API does not ask for confirmation or apply a safe-update strategy for you.

That behavior is fine for disposable cache files, but it is risky for user data, installers, or files that must survive partial download failures. In practice, most production code adds an explicit overwrite policy instead of relying on the default.

What DownloadFileAsync Actually Does

DownloadFileAsync starts an asynchronous transfer and returns immediately. The actual file write happens in the background, and completion is reported through the DownloadFileCompleted event. If the target path already exists, the new content replaces it when the download succeeds.

Here is a minimal example:

csharp
1using System;
2using System.Net;
3
4class Program
5{
6    static void Main()
7    {
8        using var client = new WebClient();
9
10        client.DownloadFileCompleted += (_, e) =>
11        {
12            if (e.Error != null)
13            {
14                Console.WriteLine($"download failed: {e.Error.Message}");
15                return;
16            }
17
18            if (e.Cancelled)
19            {
20                Console.WriteLine("download cancelled");
21                return;
22            }
23
24            Console.WriteLine("download finished");
25        };
26
27        client.DownloadFileAsync(
28            new Uri("https://example.com/archive.zip"),
29            "archive.zip");
30
31        Console.ReadLine();
32    }
33}

The important thing is that the call itself does not guarantee success. It only schedules the transfer. You need the completion event to know whether the final file on disk is valid.

Add an Explicit Overwrite Policy

If overwriting is not always acceptable, decide that before the download starts. The simplest policy is to fail fast when the file already exists:

csharp
1using System;
2using System.IO;
3using System.Net;
4
5static void DownloadIfMissing(Uri uri, string path)
6{
7    if (File.Exists(path))
8        throw new IOException($"Refusing to overwrite existing file: {path}");
9
10    using var client = new WebClient();
11    client.DownloadFile(uri, path);
12}

Another common policy is versioned output, where a new filename is generated instead of replacing the old one:

csharp
1using System;
2using System.IO;
3
4static string MakeUniquePath(string directory, string fileName)
5{
6    string baseName = Path.GetFileNameWithoutExtension(fileName);
7    string extension = Path.GetExtension(fileName);
8    string stamp = DateTime.UtcNow.ToString("yyyyMMddHHmmss");
9    return Path.Combine(directory, $"{baseName}-{stamp}{extension}");
10}

This is useful for audit trails, downloaded reports, or packages you may need to compare later.

Safer Updates: Temporary File Then Replace

The bigger problem is not only overwrite behavior. It is incomplete replacement. If a connection drops halfway through a direct write, the file at the destination may be unusable. A safer pattern is:

  1. download to a temporary file
  2. validate the result
  3. move or replace the final file only after success
csharp
1using System;
2using System.IO;
3using System.Net;
4
5static void SafeReplaceDownload(Uri uri, string destination)
6{
7    string tempPath = destination + ".tmp";
8
9    using (var client = new WebClient())
10    {
11        client.DownloadFile(uri, tempPath);
12    }
13
14    if (new FileInfo(tempPath).Length == 0)
15        throw new InvalidOperationException("Downloaded file is empty");
16
17    if (File.Exists(destination))
18        File.Replace(tempPath, destination, null);
19    else
20        File.Move(tempPath, destination);
21}

This pattern is much safer for binaries, configuration files, and anything else that should never be left half-written.

Prefer HttpClient in New Code

WebClient still exists, but it is considered legacy for new development. HttpClient gives you better control over streaming, headers, cancellation, timeouts, and file handling.

csharp
1using System.IO;
2using System.Net.Http;
3using System.Threading.Tasks;
4
5static async Task DownloadWithPolicyAsync(HttpClient client, string url, string path)
6{
7    if (File.Exists(path))
8        throw new IOException("Destination already exists");
9
10    await using Stream source = await client.GetStreamAsync(url);
11    await using FileStream target = File.Create(path);
12    await source.CopyToAsync(target);
13}

If you are writing a new downloader today, HttpClient is usually the better foundation.

Common Pitfalls

The most common mistake is assuming "async" means "safe." It only means the call returns before the work completes. You still have to handle errors, cancellation, and file integrity yourself.

Another common problem is writing directly to the final path without any validation. That is how a valid file gets replaced by a corrupt or partial one during a network interruption.

People also forget that legacy APIs encourage legacy designs. WebClient makes trivial downloads easy, but once you need retry logic, hash validation, progress tracking, or cancellation, the abstraction becomes limiting.

Finally, do not treat the absence of an exception at call time as proof that the download succeeded. With DownloadFileAsync, the real outcome is only known when the completion event fires.

Summary

  • 'WebClient.DownloadFileAsync overwrites an existing destination file by default.'
  • The method starts work asynchronously, so success is reported later through completion events.
  • Add your own overwrite policy if existing files must be preserved.
  • Download to a temporary file first when integrity matters.
  • Prefer HttpClient for new code that needs more control.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.