Guruprakash
Guruprakash

Reputation: 139

How to download files from google drive and save to a folder on local using C#

I need to download files from google drive and save to a folder on local using C#. I have done as described in Google Developer API documentation but I'm getting the file with an invalid format. Please suggest how to download it.

I done:

downloadUrl = url of the file (eg: https://drive.google.com/uc?id=1ULNeKdDoCRmWgPPBW8-d1EGUZgqvA1Ul&export=download)<br/>
filename = some name with extension


private bool SaveToDir(string downloadUrl,string filename) {
string filePath = Server.MapPath("imports/");
bool resp = false;
DriveService ds = new DriveService();
Uri temp = new Uri(downloadUrl);
string fileId = HttpUtility.ParseQueryString(temp.Query).Get("id");
var req = ds.Files.Get(fileId.Trim());
var stream = new MemoryStream();
req.MediaDownloader.ProgressChanged += (Google.Apis.Download.IDownloadProgress dp)=> {
switch (dp.Status)
{
 case Google.Apis.Download.DownloadStatus.Downloading:
      Message("downloading, please wait....");
      break;
 case Google.Apis.Download.DownloadStatus.Completed:
      using (FileStream file = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                stream.WriteTo(file);
                Message("File Downloaded successfully.");
            }
      resp = true;
      break;
 case Google.Apis.Download.DownloadStatus.Failed:
      Message("Failed to Download.");
      resp = false;
      break;
 }
 };
 req.Download(stream);

Upvotes: 0

Views: 8061

Answers (3)

Francesco
Francesco

Reputation: 2042

In my opinion the process is this:

  1. export the file to pdf;
  2. save the pdf in a folder of the server,
  3. download the pdf locally.

First

public static void ExportFileToPdf(string fileId, string newFileName)
    {
        DriveService service = (DriveService)GetService();

        string FolderPath = HostingEnvironment.MapPath("~/Myfolder/");

        // F: effettua la richiesta
        FilesResource.ExportRequest request = service.Files.Export(fileId, "application/pdf");

        string FilePath = Path.Combine(FolderPath, newFileName);

        string fPath = FilePath;

        MemoryStream outputStream = new MemoryStream();

        request.MediaDownloader.ProgressChanged += (IDownloadProgress progress) =>
         {
             switch (progress.Status)
             {
                 case DownloadStatus.Downloading:
                     {
                         Console.WriteLine(progress.BytesDownloaded);
                         break;
                     }
                 case DownloadStatus.Completed:
                     {
                         Console.WriteLine("Download complete.");
                         SaveStream(outputStream, fPath);
                         break;
                     }
                 case DownloadStatus.Failed:
                     {
                         Console.WriteLine("Download failed.");
                         break;
                     }
             }

         };

        request.Download(outputStream);

        DownloadFile("~/Myfolder/", newFileName);
    }

Second

        private static void SaveStream(MemoryStream stream, string FilePath)
    {
        using (FileStream file = new FileStream(FilePath, FileMode.Create, FileAccess.ReadWrite))
        {
            stream.WriteTo(file);
        }

    }

Third

        private static void DownloadFile(string folderName, string fileName)
    {
        HttpResponse response = HttpContext.Current.Response;

        response.ClearContent();

        response.Clear();

        response.ContentType = "application/pdf";

        response.AddHeader("Content-Disposition", "attachment; filename=" + fileName + ";");

        response.TransmitFile(HostingEnvironment.MapPath(folderName+fileName));

        response.Flush();

        response.End();
    }

If we need to download important documents like receipts or invoices, we can also implement a control to verify if the file is already present in the server, instead of continuos pdf export.

Upvotes: 2

Thulfiqar
Thulfiqar

Reputation: 392

    void SaveStream(System.IO.MemoryStream stream, string saveTo)
    {
        using (System.IO.FileStream file = new System.IO.FileStream(saveTo, System.IO.FileMode.Create, System.IO.FileAccess.Write))
        {
            stream.WriteTo(file);
        }
    }

// code here

  SaveStream( dwnldstream, "C:\\Users\\thulfiqar\\Downloads\\photo.jpg");

please refer to this tutorial and note that "stream" in your code is corresponding to "dwnldstream" in my code.

Upvotes: 0

Linda Lawton - DaImTo
Linda Lawton - DaImTo

Reputation: 116958

If the file type is a google document type then you need to preform an export you cant just use the downloadurl link

var fileId = "1ZdR3L3qP4Bkq8noWLJHSr_iBau0DNT4Kli4SxNc2YEo";
var request = driveService.Files.Export(fileId, "application/pdf");
var stream = new System.IO.MemoryStream();
// Add a handler which will be notified on progress changes.
// It will notify on each chunk download and when the
// download is completed or failed.
request.MediaDownloader.ProgressChanged +=
        (IDownloadProgress progress) =>
{
    switch (progress.Status)
    {
        case DownloadStatus.Downloading:
            {
                Console.WriteLine(progress.BytesDownloaded);
                break;
            }
        case DownloadStatus.Completed:
            {
                Console.WriteLine("Download complete.");
                break;
            }
        case DownloadStatus.Failed:
            {
                Console.WriteLine("Download failed.");
                break;
            }
    }
};
request.Download(stream);

Upvotes: 0

Related Questions