除了上传常规正文之外,多种 API 方法还支持上传媒体内容。在这种情况下,常规请求方法会过载,以获取额外的 Stream
进行上传。
概览
对于您要上传的任何 Stream
,应使用可续传媒体上传,以便以较小的分块上传串流。
如果您要传输大型文件,并且发生网络中断或某些其他传输故障的可能性较高,这种方法特别有用。
此外,它还可以在发生网络故障时减少带宽使用量,因为您不必从头开始重新上传大型文件。
ResumableMediaUpload
从 1.2.0-beta 版开始,可续传媒体上传功能已成为 Google API .NET 客户端库中的一项功能。Google API 专用库包含可与此功能互动的便捷方法。
例如,Drive API 的媒体上传页面上介绍了可续传媒体上传协议。感兴趣的主类是 ResumableUpload
。在此实现中,媒体内容以分块的形式上传。
默认分块大小为 10MB,但您可以通过将请求的 ChunkSize
属性设置为 256KB 的任意倍数来更改大小。
如果请求遇到服务器错误,系统会使用指数退避算法政策来重新发送未成功上传的字节。
默认情况下,系统会为每个客户端请求启用指数退避算法。
您可以在构建新服务对象时更改默认行为,方法是更改 BaseClientService.Initializer
上的
DefaultExponentialBackOffPolicy
属性,并/或将
HttpClientInitializer
属性设置为您自己的 IConfigurableHttpClientInitializer
实现(这会添加一些退避政策)。
API 专属文档的参考文档中标识了支持媒体上传的方法。
对于这些 API 方法,添加了便捷的 Upload
和 UploadAsync
方法。这些方法将上传的 Stream
及其内容类型作为参数。
请确保您上传的流的位置为 0,否则会收到错误,如“System.InvalidOperationException: The given header 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");