2017-08-13 2 views
1

Ich möchte den unterbrochenen fortsetzbaren Upload mit Google Drive v3 C# SDK fortsetzen. Der Grund, warum ich dies möchte, besteht darin, einen resumefähigen Upload in Restful Web API zu erstellen. Es gibt Google Drive API-Instanz in diesem RestAPI, so dass Chunk-Daten von Client-Programm auf Google Drive weitergeleitet wird. Wie Sie wissen, kann das Client-Programm nicht ganze Dateidaten gleichzeitig in die Web-API hochladen. Daher müssen wir den unterbrochenen fortsetzbaren Upload fortsetzen.Fortsetzung des unterbrochenen Uploads mit Google Drive v3 C# sdk

Also mein Plan ist hier.

  • Zuerst müssen wir eine Upload-Sitzung erstellen und Session-URI empfangen.
  • Zweitens, erstellen Upload-Instanz jedes Mal von zurückgegebenen URI und Chunk-Daten hinzufügen.
  • Drittens wiederholen Sie den zweiten Prozess bis EOF.

Dafür habe ich Testcode gemacht, aber es funktioniert überhaupt nicht.

Ehrlich gesagt, erwartete ich 308 Resume Incomplete Code, aber das Ergebnis ist anders.

"Ungültige Anfrage. Nach dem Content-Range-Header ist die endgültige Größe des Uploads 262144 Byte (s). Dies entspricht nicht der erwarteten Größe von 1193188 Byte (s), die in einer früheren Anfrage angegeben wurde . "

Das bedeutet, dass ich Code erstellen muss, der unterbrochenen fortsetzbaren Upload mit Google Drive C# SDK fortgesetzt wird.

Wer kann mir helfen?

Antwort

1

Schließlich habe ich Problem gelöst. Der genaue Code ist unten. Eigentlich konnte ich bei Google keinen Quellcode finden, also war ich so traurig. Jeder Entwickler, der dieses Problem lösen möchte, benutzt bitte meinen Code. Ich hoffe, dir geht es gut. :)

public static async Task<Google.Apis.Drive.v3.Data.File> UploadSync(DriveService driveService, string filepath) 
    { 
     string destfilename = Path.GetFileName(filepath); 

     List<string> parents = new List<string>(); 

     parents.Add("root"); 
     // Prepare the JSON metadata 
     string json = "{\"name\":\"" + destfilename + "\""; 
     if (parents.Count > 0) 
     { 
      json += ", \"parents\": ["; 
      foreach (string parent in parents) 
      { 
       json += "\"" + parent + "\", "; 
      } 
      json = json.Remove(json.Length - 2) + "]"; 
     } 
     json += "}"; 
     Debug.WriteLine(json); 

     Google.Apis.Drive.v3.Data.File uploadedFile = null; 
     try 
     { 
      System.IO.FileInfo info = new System.IO.FileInfo(filepath); 

      ulong fileSize = (ulong)info.Length; 

      var uploadStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open, System.IO.FileAccess.Read); 

      var insert = driveService.Files.Create(new Google.Apis.Drive.v3.Data.File { Name = destfilename, Parents = new List<string> { "root" } }, uploadStream, "application/octet-stream"); 

      Uri uploadUri = insert.InitiateSessionAsync().Result; 

      int chunk_size = ResumableUpload.MinimumChunkSize; 
      int bytesSent = 0; 
      while (uploadStream.Length != uploadStream.Position) 
      { 
       byte[] temp = new byte[chunk_size]; 
       int cnt = uploadStream.Read(temp, 0, temp.Length); 
       if (cnt == 0) 
        break; 

       HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(uploadUri); 

       httpRequest.Method = "PUT"; 
       httpRequest.Headers["Authorization"] = "Bearer " + ((UserCredential)driveService.HttpClientInitializer).Token.AccessToken; 
       httpRequest.ContentLength = (long)cnt; 
       httpRequest.Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", bytesSent, bytesSent + cnt - 1, fileSize); 

       using (System.IO.Stream requestStream = httpRequest.GetRequestStreamAsync().Result) 
       { 
        requestStream.Write(temp, 0, cnt); 
       } 

       HttpWebResponse httpResponse; 
       try 
       { 
        httpResponse = (HttpWebResponse)httpRequest.GetResponse(); 
       } 
       catch (WebException ex) 
       { 
        httpResponse = (HttpWebResponse)ex.Response; 
       } 

       if (httpResponse.StatusCode == HttpStatusCode.OK) 
       { } 
       else if ((int)httpResponse.StatusCode != 308) 
        break; 

       bytesSent += cnt; 

       Console.WriteLine("Uploaded " + bytesSent.ToString()); 
      } 

      if (bytesSent != uploadStream.Length) 
      { 
       return null; 
      } 

      // Try to retrieve the file from Google 
      FilesResource.ListRequest request = driveService.Files.List(); 
      if (parents.Count > 0) 
       request.Q += "'" + parents[0] + "' in parents and "; 
      request.Q += "name = '" + destfilename + "'"; 
      FileList result = request.Execute(); 
      if (result.Files.Count > 0) 
       uploadedFile = result.Files[0]; 
     } 
     catch (Exception ex) 
     { 
      Debug.WriteLine(ex.Message); 
     } 

     return uploadedFile; 
    } 
+0

Ich bezweifle sehr, dass dies erforderlich ist - 'ResumableUpload' sollte diese Situation behandeln, nur nicht mit Ihrem vorhandenen Code. Ich schaue es mir heute an, obwohl ich die Speicher-API als ein einfacheres Beispiel für die Verwendung von 'ResumableUpload' verwende. –

+0

Wie oben erwähnt, wird dies nur benötigt, wenn wir eine restliche API erstellen. – Dennis

+0

Wir können nicht alle Dateidaten zu einem Zeitpunkt hochladen, wenn wir Restful verwenden, das zwischen Programm und Google API vermittelt. – Dennis

Verwandte Themen