Некоторые методы API поддерживают загрузку медиаконтента в дополнение к обычному телу запроса.
В этом случае обычный метод запроса перегружается, чтобы получить дополнительный объект Stream для загрузки.
Обзор
Для загрузки Stream любого размера следует использовать возобновляемую загрузку медиаконтента, которая позволяет загружать потоки небольшими фрагментами.
Это особенно полезно при передаче больших файлов, когда высока вероятность сбоя сети или другой ошибки передачи.
Кроме того, это позволяет снизить нагрузку на сеть в случае сбоев, поскольку вам не придется заново загружать большие файлы.
ResumableMediaUpload
Возобновляемая загрузка медиаконтента поддерживается в клиентской библиотеке API Google для .NET начиная с версии 1.2.0-beta. Библиотеки, предназначенные для работы с API Google, содержат удобные методы для взаимодействия с этой функцией.
Протокол возобновляемой загрузки медиафайлов описан, например, на странице загрузки медиафайлов для Drive API.
Основной класс – ResumableUpload.
В этой реализации медиаконтент загружается частями.
По умолчанию размер фрагмента составляет 10 МБ, но вы можете изменить его, задав для свойства ChunkSize в запросе любое значение, кратное 256 КБ.
Если при обработке запроса возникает ошибка сервера, то для повторной отправки байтов, которые не удалось загрузить, используется экспоненциальная выдержка.
По умолчанию экспоненциальная выдержка включена для каждого запроса клиента.
Вы можете изменить режим работы по умолчанию при создании нового объекта сервиса, изменив свойство DefaultExponentialBackOffPolicy в BaseClientService.Initializer и/или задав для свойства HttpClientInitializer собственную реализацию IConfigurableHttpClientInitializer, которая добавляет правила отсрочки.
Методы, поддерживающие загрузку медиаконтента, указаны в справочной документации по API.
Для этих методов API добавлены удобные методы Upload и UploadAsync.
Эти методы принимают в качестве параметров объект Stream, который нужно загрузить, и тип его контента.
Убедитесь, что позиция загружаемого потока равна 0, иначе вы получите ошибку, например "System.InvalidOperationException: The given header was not found".
Обратите внимание, что из-за особенностей работы класса 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");