使用 Google 云端硬盘 v3 C# SDK 恢复中断的上传



我想使用 Google Drive v3 C# SDK 恢复中断的断点续传上传。 我想要这样做的原因是在 Restful Web API 中创建可恢复上传。 这个 RestAPI 中有谷歌驱动器 API 实例,所以这是将块数据从客户端程序中继到 谷歌驱动器。 如您所知,客户端程序无法一次将整个文件数据上传到 Web API,因此我们需要恢复中断的可恢复上传。

所以我的计划就在这里。

  • 首先,我们需要创建上传会话并接收会话 URI。
  • 其次,每次从返回的 URI 创建上传实例并添加区块数据。
  • 第三,重复第二个过程直到EOF。

为此,我制作了测试代码,但它根本不起作用。

var uploadStream = new System.IO.FileStream(UploadFileName, System.IO.FileMode.Open,
System.IO.FileAccess.Read);
var insert = service.Files.Create(new Google.Apis.Drive.v3.Data.File { Name = title }, uploadStream, ContentType);
Uri uploadUri = insert.InitiateSessionAsync().Result;
int chunk_size = ResumableUpload.MinimumChunkSize;
while (uploadStream.Length != uploadStream.Position)
{
byte[] temp = new byte[chunk_size];
uploadStream.Read(temp, 0, temp.Length);
MemoryStream stream = new MemoryStream(temp);
ResumableUpload resume_uploader = ResumableUpload.CreateFromUploadUri(uploadUri, stream);
resume_uploader.ChunkSize = chunk_size;
IUploadProgress ss =  resume_uploader.Resume();
Console.WriteLine("Uploaded " + ss.BytesSent.ToString());
}   

坦率地说,我预计会收到 308 简历不完整代码,但结果不同。

"无效请求。 根据内容范围标头,上传的最终大小为 262144 字节。这与之前请求中指定的1193188字节的预期大小不匹配。

这意味着我需要创建代码来恢复使用 Google Drive C# SDK 中断的可恢复上传。

有人可以帮助我吗?

最后,我解决了问题。确切的代码如下。实际上,我在谷歌上找不到任何源代码,所以我很伤心。每个想要解决此问题的开发人员,请使用我的代码。希望你没事。:)

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;
}

最新更新