2016-09-27 4 views
0

Frage:Massendatei herunterladen - Drive API .NET

Wie kann ich mein Backup-Tool, um alle Dateien, die es in Fileids aufgezeichnet?

Die Methode, die ich verwendet habe, ist C# /. NET https://developers.google.com/drive/v3/web/manage-downloads#examples

Ich werde die langweiligen Details ersparen und diesen Teil meines Programmprotokolle sagen in Sobald als jeden Benutzer (na ja, das Apps-Service-API), packt alle Datei-IDs ihrer Dateien und speichert sie in einer flachen Textdatei. Mein Programm öffnet dann diese flache Textdatei und beginnt mit dem Herunterladen jeder für diesen Benutzer aufgezeichneten Datei-ID, aber das Problem ist: es ist so langsam, weil es eine neue Verbindung für eine Datei öffnet, auf den Abschluss der Datei wartet, dann eine neue Datei-ID erhält und startet der ganze Prozess von neuem. Es ist nicht sehr effizient.

Googles Beispiel, das ich ziemlich viel Verbatim kopiert (I verändert die ein wenig Vars von sofort greifen und ihre MIME-Typ zu exportieren, so dass die ersten drei Zeilen sind strittig):

var fileId = "0BwwA4oUTeiV1UVNwOHItT0xfa2M"; 
var request = driveService.Files.Get(fileId); 
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); 

Gibt es ich Jede Art und Weise kann dies rationalisieren, so dass mein Programm alle Dateien herunterladen kann, die es für den Benutzer in einem großen Handshake kennt, vs eine Datei einzeln lesen, dann eine Sitzung öffnen, exportieren, herunterladen, schließen und dann dasselbe für die nächste Datei tun? Hoffe, das macht Sinn.

Vielen Dank für jede Hilfe vor der Zeit!

--Mike

--- EDIT ---

wollte ich mehr Details hinzufügen, so dass hoffentlich, was ich suche mehr Sinn zu tun macht:

Also, was ist passiert im folgenden Code ist: Ich erstelle eine "Anfrage", die mich den Dateityp exportieren kann (die ich von der flachen Textdatei als Datei-ID [0] habe, und die "Mimetype", die im Array als FileId ist 1].) Was die Geschwindigkeit des Programms killt, ist, die "BuildService" -Anforderung für jedes ti zu erstellen Ich für jede Datei.

foreach (var file in deltafiles) 
{ 
    try 
    { 
    if (bgW.CancellationPending) 
    { 
     stripLabel.Text = "Backup canceled!"; 
     e.Cancel = true; 
     break; 
     } 
     DateTime dt = DateTime.Now; 
     string[] foldervalues = File.ReadAllLines(savelocation + "folderlog.txt"); 
     cnttototal++; 
     bgW.ReportProgress(cnttototal); 
     // Our file is a CSV. Column 1 = file ID, Column 2 = File name 
     var values = file.Split(','); 

     string fileId = values[0]; 
     string fileName = values[1]; 
     string mimetype = values[2]; 
     mimetype = mimetype.Replace(",", "_"); 
     string folder = values[3]; 
     int foundmatch = 0; 
     int folderfilelen = foldervalues.Count(); 

     fileName = fileName.Replace('\\', '_').Replace('/', '_').Replace(':', '_').Replace('!', '_').Replace('\'', '_').Replace('*', '_').Replace('#', '_').Replace('[', '_').Replace(']', '_'); 

     var request = CreateService.BuildService(user).Files.Export(fileId, mimetype); 

     //Default extensions for files. Not sure what this should be, so we'll null it for now. 
     string ext = null; 

     // Things get sloppy here. The reason we're checking MimeTypes 
     // is because we have to export the files from Google's format 
     // to a format that is readable by a desktop computer program 
     // So for example, the google-apps.spreadsheet will become an MS Excel file. 
     if (mimetype == mimeSheet || mimetype == mimeSheetRitz || mimetype == mimeSheetml) 
     { 
      request = CreateService.BuildService(user).Files.Export(fileId, exportSheet); 
      ext = ".xls"; 
     } 
     if (mimetype == mimeDoc || mimetype == mimeDocKix || mimetype == mimeDocWord) 
     { 
      request = CreateService.BuildService(user).Files.Export(fileId, exportDoc); 
      ext = ".docx"; 
     } 
     if (mimetype == mimePres || mimetype == mimePresPunch) 
     { 
      request = CreateService.BuildService(user).Files.Export(fileId, exportPres); 
      ext = ".ppt"; 
     } 
     if (mimetype == mimeForm || mimetype == mimeFormfb || mimetype == mimeFormDrawing) 
     { 
      request = CreateService.BuildService(user).Files.Export(fileId, exportForm); 
      ext = ".docx"; 
     } 
     // Any other file type, assume as know what it is (which in our case, will be a txt file) 
     // apply the mime type and carry on. 
     string dest = Path.Combine(savelocation, fileName + ext); 
     var stream = new System.IO.FileStream(dest, FileMode.Create, FileAccess.ReadWrite); 
     int oops = 0; 
     // 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: 
       { 
        throw new Exception("File may be corrupted."); 
        break; 
        } 
       case DownloadStatus.Completed: 
       { 
        Console.WriteLine("Download complete."); 
        break; 
       } 
       case DownloadStatus.Failed: 
       { 
        oops = 1; 
        logFile.WriteLine(fileName + " could not be downloaded. Possible Google draw/form OR bad name.\n"); 
        break; 
       } 
      } 
     }; 
     request.Download(stream); 
     stream.Close(); 
     stream.Dispose(); 

Gibt es eine Möglichkeit, diesen Prozess optimieren könnte, damit ich das Laufwerk Dienst nicht bauen müssen, um eine Datei jedes Mal mag ich zum Download? Der flache Text der Programmdatei liest ähnelt

FILEID, tatsächliche Dateiname, MIMETYPE

So ist es eine Möglichkeit, den mittleren Mann herausgeschnitten konnte und die request.Download Methode ernähren, ohne ständig die „foreach erinnert "Anweisung, den Dateityp als Dateisystem-lesbare Datei zu exportieren? (Gute Trauer, tut mir leid, ich weiß, das hört sich nach viel an.)

Alle Zeiger wären toll !!

Antwort

0

Sie können das Lernprogramm versuchen: Google Drive API with C# .net – Download. Dies ist ein viel einfacherer Code zum Herunterladen einer Datei. Es gibt auch andere Faktoren wie unterbrochene Internetverbindung, die sich auf die ETA des Herunterladens der Datei auswirken kann.

Codebeispiel:

/// Download a file 
/// Documentation: https://developers.google.com/drive/v2/reference/files/get 
/// 

/// a Valid authenticated DriveService 
/// File resource of the file to download 
/// location of where to save the file including the file name to save it as. 
/// 
public static Boolean downloadFile(DriveService _service, File _fileResource, string _saveTo) 
{ 

if (!String.IsNullOrEmpty(_fileResource.DownloadUrl)) 
{ 
try 
{ 
var x = _service.HttpClient.GetByteArrayAsync(_fileResource.DownloadUrl); 
byte[] arrBytes = x.Result; 
System.IO.File.WriteAllBytes(_saveTo, arrBytes); 
return true; 
} 
catch (Exception e) 
{ 
Console.WriteLine("An error occurred: " + e.Message); 
return false; 
} 
} 
else 
{ 
// The file doesn't have any content stored on Drive. 
return false; 
} 
} 

Mit _service.HttpClient.GetByteArrayAsync können wir es die Download-URL der Datei passieren wir herunterladen möchten. Sobald die Datei heruntergeladen ist, ist es eine einfache Sache, die Datei auf die Festplatte zu schreiben.

Hoffe, das hilft!

+0

Danke! Ich schätze den Link :-) Ich habe versucht, das früher zu erwähnen, als ich gerade anfing, aber ich entschied mich dafür, sdk v3 zu fahren, da es so aussah, als würde v2 bald "EOL" sein. –

0

Dies ist keine Antwort so viel wie es eine Arbeit ist, auch dann ist es nur die halbe Antwort (für jetzt.) Ich warf meine Handschuhe aus und spielte schmutzig.

Zuerst habe ich meine nugget google API-Pakete auf die neueste Version aktualisiert, die heute in meinem VS-Projekt verfügbar ist, ging dann zu https://github.com/google/google-api-dotnet-client, gab es/klonte es, änderte die Google.Apis.Drive.v3.cs-Datei (die kompiliert zu google.apis.drive.v3.dll), so dass der MIME-Typ nicht mehr nur gelesen werden kann (es kann get; und set ;, wenn es standardmäßig nur get erlaubt).

Da ich bereits die MIME-Typen kannte, kann ich den MIME-Typ jetzt erzwingen und nun mit meinem Leben fortfahren, anstatt den Client-Dienst aufbauen zu müssen, nur um den Dateityp zu exportieren Ich weiß es schon.

Es ist nicht schön, nicht wie es gemacht werden sollte, aber das hat mich wirklich gestört!

Zurück zu @ Mr.Rebot, ich danke Ihnen noch einmal für Ihre Hilfe und Forschung! :-)