Download Files from Google Drive in C#

There are multiple ways to download files from Google Drive, some of which require authentication and others that require lots of code. Here’s the simplest way to download the files, provided you’ve got the right file url.

var url = "https://drive.google.com/uc?export=download&id=<file_id>";
var path = "<add temp file path where file should be downloaded>";

using (var client = new HttpClient())
{
    using (var s = client.GetStreamAsync(url))
    {
        using (var fs = new FileStream(path, FileMode.OpenOrCreate))
        {
            s.Result.CopyTo(fs);
        }
    }
}

The above approach also works when writing to memory stream, instead of copying to a file stream, copy to a new MemoryStream variable:

using (var client = new HttpClient())
{
    using (var s = client.GetStreamAsync(url))
    {
        using (var ms = new MemoryStream())
        {
            s.Result.CopyTo(ms);
            var fileBytes = ms.ToArray(); // use the bytes as needed
        }
    }
}

Getting the File ID

The file ID is the long string of characters in your Google Drive sharing URL after /d/ and before /view. For example, if your Google Drive URL is:

https://drive.google.com/file/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/view

The file ID would be:

1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms

If users paste the full sharing link into your application, you can pull the ID out with a regular expression rather than asking them to do it by hand:

using System.Text.RegularExpressions;

public static string GetGoogleDriveFileId(string shareUrl)
{
    // Matches both .../file/d/<id>/view and ...?id=<id> formats
    var match = Regex.Match(shareUrl, @"(?:/d/|[?&]id=)([a-zA-Z0-9_-]+)");

    if (!match.Success)
    {
        throw new ArgumentException("Could not find a Google Drive file ID in the URL.", nameof(shareUrl));
    }

    return match.Groups[1].Value;
}

Downloading Larger Files

Reading the whole file into memory is fine for small files, but for larger files it is better to stream the response directly to disk. Using HttpCompletionOption.ResponseHeadersRead tells HttpClient to return as soon as the headers arrive, rather than buffering the entire body first:

private static readonly HttpClient Client = new HttpClient();

public static async Task DownloadToFileAsync(string fileId, string destinationPath)
{
    var url = 
quot;https://drive.google.com/uc?export=download&id={fileId}"; using var response = await Client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); await using var source = await response.Content.ReadAsStreamAsync(); await using var target = new FileStream(destinationPath, FileMode.Create, FileAccess.Write, FileShare.None); await source.CopyToAsync(target); }

Notice that the HttpClient is declared once as a static readonly field. Creating a new HttpClient for every request can exhaust the available sockets when downloading lots of files, so reusing a single instance (or using IHttpClientFactory in ASP.NET Core) is the recommended approach.

Check That You Got the File (Not a Web Page)

When Google Drive can't serve a file directly (for example, because the file isn't shared, or because it is too large to be virus-scanned), it returns an HTML page instead of the file, often with a 200 OK status. Your code will happily save that page with your file's name unless you check for it. A simple safeguard is to inspect the content type before saving:

var mediaType = response.Content.Headers.ContentType?.MediaType;

if (mediaType == "text/html")
{
    throw new InvalidOperationException(
        "Google Drive returned a web page instead of the file. " +
        "Check that the file is shared with 'Anyone with the link' and isn't too large for direct download.");
}

Limitations

For this method to work, the file needs to be shared publicly (or with link sharing enabled) and the file permissions need to allow downloads. Be aware of the following limitations:

  • Private files can't be downloaded this way
  • Large files may trigger Google Drive's "can't scan this file for viruses" confirmation page
  • Google Drive's download quotas still apply
  • There is no built-in retry logic, so you'll need to add your own (or use a library like Polly) if network failures are a concern

When to Use the Google Drive API Instead

The direct-link approach is ideal for quick automations and publicly shared files. Switch to the official Google Drive API and the Google.Apis.Drive.v3 NuGet package when you need to:

  • Download private files using a service account or user sign-in
  • Download Google Docs, Sheets or Slides (these must be exported to a format such as PDF or XLSX rather than downloaded directly)
  • List, search or monitor folders for new files
  • Reliably download very large files
  • Upload or update files as well as download them

The API requires a bit more setup (a Google Cloud project, credentials and OAuth scopes) but gives you full, supported control over Drive.