上传媒体

除了支持上传常规正文外,一些 API 方法还支持上传媒体内容。 在这种情况下,常规请求方法会过载,以获取额外的 Stream即可上传。

概览

对于您要上传的任何 Stream,您都应使用可续传 媒体上传,允许以较小的数据块上传视频流。 如果您要传输大型文件,或者发生网络中断或其他传输故障的几率较高,您会发现该协议特别实用。 还可以减少网络故障时对带宽的占用 因为您不必从头开始重新上传大型文件。

ResumableMediaUpload

可续传媒体上传是 Google API .NET 客户端库中的一项功能 从 1.2.0-beta 开始。 特定于 Google API 的库包含用于与此功能交互的便捷方法。

例如,Drive API 的媒体上传页面介绍了可恢复的媒体上传协议。 主要关注的类是 ResumableUpload。在此实现中,媒体内容以数据块的形式上传。

默认数据块大小为 10MB,但您可以通过 将请求中的 ChunkSize 属性设置为 256KB 的任意倍数。 如果请求中遇到服务器错误,系统会使用指数退避算法来重新发送未成功上传的字节。 默认情况下,系统会为每个客户端请求启用指数退避。 您可以通过更改 BaseClientService.Initializer 上的 DefaultExponentialBackOffPolicy 属性和/或将 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");