如何从Google云端硬盘下载大文件

时间:2019-02-07 00:05:44

标签: c#

我需要一个代码才能从Google云端硬盘下载大文件。

我使用以下代码:

using System;
using System.ComponentModel;
using System.Net;
using System.Threading;

namespace CF_Examples
{
    class Program
    {
        static ManualResetEvent mre = new ManualResetEvent(false);
        static int currentPercent;

        static void Main(string[] args)
        {
            new Thread(DownloadThread).Start();
        }

        static void DownloadThread()
        {
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            using (var webClient = new WebClient())
            {
                if (Console.IsOutputRedirected)
                    webClient.DownloadProgressChanged += OnDownloadProgressChanged_Simple;
                else
                    webClient.DownloadProgressChanged += OnDownloadProgressChanged_Nice;
                webClient.DownloadFileCompleted += OnDownloadFileCompleted;
                currentPercent = -1;
                webClient.DownloadFileAsync(new Uri("https://docs.google.com/uc?export=download&id=0BzR3oIFOFwL3eEpWeVFCS002dms"), "file.zip");
                mre.WaitOne();
            }
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
        }

        static void OnDownloadProgressChanged_Nice(object sender, DownloadProgressChangedEventArgs e)
        {
            int prevPercent = Interlocked.Exchange(ref currentPercent, e.ProgressPercentage);
            if (e.ProgressPercentage != prevPercent)
            {
                const int maxLen = 50;
                string progress = new string('=', (int)(maxLen * (e.ProgressPercentage / 100.0)));
                progress = "[" + progress.PadRight(maxLen) + "] " + e.ProgressPercentage + "%";
                Console.CursorLeft = 0;
                Console.Write(progress);
            }
        }

        static void OnDownloadProgressChanged_Simple(object sender, DownloadProgressChangedEventArgs e)
        {
            int prevPercent = Interlocked.Exchange(ref currentPercent, e.ProgressPercentage);
            if (e.ProgressPercentage != prevPercent)
            {
                Console.Write("{0}% ", e.ProgressPercentage);
            }
        }

        static void OnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            Console.WriteLine();
            mre.Set();
        }
    }
}

下载小文件(30-70 Mb)不会出现问题。

如何才能下载1,5,10 GB的文件?

P.S。该示例包含一个指向1.6 GB文件的链接。

此代码显示文件上传过程。

2 个答案:

答案 0 :(得分:0)

对于大文件,Google云端硬盘会要求您输入确认码。 这是用于确认的按钮的HTML代码:

<a id="uc-download-link" class="goog-inline-block jfk-button jfk-button- action" href="/uc? export=download&amp;confirm=XWPY&amp;id=0BzR3oIFOFwL3eEpWeVFCS002dms">Download anyway</a>

因此,首先发出GET请求,并在链接的代码[link] gist.github.com/yasirkula/d0ec0c07b138748e5feaecbd93b6223c中使用第82-90行从响应中获取 confirm = XWPY 然后像这样使用它     [link] docs.google.com/uc?export=download&confirm=XWPY&id=0BzR3oIFOFwL3eEpWeVFCS002dms

答案 1 :(得分:0)

Python-仅使用Google Drive API的解决方案

在运行下面的代码之前,您必须激活Google Drive API,安装依赖项并使用您的帐户进行身份验证。可以在原始Google Drive API guide page上找到说明。

要使用下面的代码,只需运行:

$ python drive_api_download.py --file_id <file_id> [--output output_name]

import io
import os
import pickle
import sys, argparse
from googleapiclient.discovery import build
from google.auth.transport.requests import Request
from googleapiclient.http import MediaIoBaseDownload
from google_auth_oauthlib.flow import InstalledAppFlow

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/drive.readonly']


def _main(file_id, output):
    """ Shows basic usage of the Drive v3 API.
        Prints the names and ids of the first 10 files the user has access to.
    """
    if not file_id:
        sys.exit('\nMissing arguments. Correct usage:\npython drive_api_download.py --file_id <file_id> [--output output_name]\n')
    elif not output:
        output = "./" + file_id
    
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('drive', 'v3', credentials=creds)

    # Downloads file
    request = service.files().get_media(fileId=file_id)
    fp = open(output, "wb")
    downloader = MediaIoBaseDownload(fp, request)
    done = False
    while done is False:
        status, done = downloader.next_chunk(num_retries=3)
        print("Download %d%%." % int(status.progress() * 100))

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', '--file_id')
    parser.add_argument('-o', '--output')
    args = parser.parse_args()
    
    _main(args.file_id, args.output)