上傳媒體

除了一般主體以外,還有幾種 API 方法支援上傳媒體內容。在這種情況下,系統會超載一般要求方法,以取得額外的 Stream 可供上傳。

總覽

您可以針對要上傳的任何 Stream,使用支援續傳的媒體上傳功能,以便透過較小的區塊上傳串流。如果您要傳輸大型檔案,而且發生網路中斷或其他傳輸問題的可能性很高,這個方法就特別實用。這也能在網路發生問題時降低頻寬用量,因為您不需要從頭開始上傳大型檔案。

ResumableMediaUpload

自 1.2.0-beta 版以來,Google API .NET 用戶端程式庫已推出支援續傳媒體上傳功能。Google API 專屬程式庫包含可與此功能互動的便利方法。

其中說明支援續傳媒體上傳通訊協定,例如 Drive API 的媒體上傳頁面。主要用途為 ResumableUpload。在本實作中,媒體內容是分成多個區塊上傳。

預設的區塊大小為 10 MB,但您可以透過將要求的 ChunkSize 屬性設定為 256 KB 的任意倍數來變更大小。如果要求發生伺服器錯誤,系統會使用指數輪詢政策來重新傳送未成功上傳的位元組。根據預設,系統會為每個用戶端要求啟用指數輪詢功能。您可以在建構新服務物件時變更預設行為,方法是變更 BaseClientService.Initializer DefaultExponentialBackOffPolicy 屬性,並/或將 HttpClientInitializer 屬性設為您自己的 IConfigurableHttpClientInitializer 實作,藉此新增部分輪詢政策。

如要瞭解支援媒體上傳的方法,請參閱 API 專屬說明文件的參考說明文件。在這些 API 方法中,加入了便利的 UploadUploadAsync 方法。這些方法需要 Stream 來上傳,並將其內容類型做為參數。

請確認上傳的串流位置為 0,否則您會收到「System.InvalidOperationException: 指定的標頭」等錯誤訊息。

請注意,基於架構 HttpClient 類別的行為,如果上傳逾時,系統會擲回 TaskCanceledException。 看到這個例外狀況時,請考慮在服務物件使用的用戶端中,手動增加 Timeout 屬性。

程式碼範例

// Create the service using the client credentials.
var service = new DriveService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential,
    ApplicationName = "Application_Name"
});

using var uploadStream = System.IO.File.OpenRead("Local_File_Name");

// Create the File resource to upload.
Google.Apis.Drive.v3.Data.File driveFile = new Google.Apis.Drive.v3.Data.File
{
    Name = "Drive_File_Name"
};
// Get the media upload request object.
FilesResource.CreateMediaUpload insertRequest = service.Files.Create(
    driveFile, uploadStream, "image/jpeg");

// Add handlers which will be notified on progress changes and upload completion.
// Notification of progress changed will be invoked when the upload was started,
// on each upload chunk, and on success or failure.
insertRequest.ProgressChanged += Upload_ProgressChanged;
insertRequest.ResponseReceived += Upload_ResponseReceived;

await insertRequest.UploadAsync();

static void Upload_ProgressChanged(IUploadProgress progress) =>
    Console.WriteLine(progress.Status + " " + progress.BytesSent);

static void Upload_ResponseReceived(Google.Apis.Drive.v3.Data.File file) =>
    Console.WriteLine(file.Name + " was uploaded successfully");