问题:
如何告诉我的备份工具下载它在fileids中记录的所有文件?
我使用的方法是C#/。NET https://developers.google.com/drive/v3/web/manage-downloads#examples
我将免费提供无聊的详细信息,并说我的程序的一部分以每个用户(好吧,使用Apps Service API)登录一次,抓取他们的所有文件' fileIds并将它们记录到平面文本文件中。我的程序然后打开该平面文本文件并开始下载为该用户记录的每个fileId,但问题是:它太慢了,因为它为文件打开一个新连接,等待文件完成,然后得到一个新的fileid并重新开始整个过程。效率不高。
谷歌的例子,我几乎复制了Verbatim(我通过立即抓取并导出他们的mimetype来修改vars一点,所以前三行是没有意义的):
var fileId = "0BwwA4oUTeiV1UVNwOHItT0xfa2M";
var request = driveService.Files.Get(fileId);
var stream = new System.IO.MemoryStream();
// Add a handler which will be notified on progress changes.
// It will notify on each chunk download and when the
// download is completed or failed.
request.MediaDownloader.ProgressChanged +=
(IDownloadProgress progress) =>
{
switch(progress.Status)
{
case DownloadStatus.Downloading:
{
Console.WriteLine(progress.BytesDownloaded);
break;
}
case DownloadStatus.Completed:
{
Console.WriteLine("Download complete.");
break;
}
case DownloadStatus.Failed:
{
Console.WriteLine("Download failed.");
break;
}
}
};
request.Download(stream);
有没有什么方法可以简化这一点,以便我的程序可以在一次大握手中下载它为用户知道的所有文件,而不是单独读取fileid,然后打开会话,导出,下载,关闭,然后执行下一个文件完全相同的东西?希望这是有道理的。
提前感谢您提供任何帮助!
- 麦克
--- --- EDIT
我想添加更多详细信息,以便我希望我做的更有意义:
以下代码中发生的事情是:我正在创建一个"请求"这将让我导出文件类型(我从平面文本文件中导出为fileId [0],以及" mimetype"它在数组中作为fileId [1]。) 什么杀死程序的速度是必须建立" BuildService"每次请求每个文件。
foreach (var file in deltafiles)
{
try
{
if (bgW.CancellationPending)
{
stripLabel.Text = "Backup canceled!";
e.Cancel = true;
break;
}
DateTime dt = DateTime.Now;
string[] foldervalues = File.ReadAllLines(savelocation + "folderlog.txt");
cnttototal++;
bgW.ReportProgress(cnttototal);
// Our file is a CSV. Column 1 = file ID, Column 2 = File name
var values = file.Split(',');
string fileId = values[0];
string fileName = values[1];
string mimetype = values[2];
mimetype = mimetype.Replace(",", "_");
string folder = values[3];
int foundmatch = 0;
int folderfilelen = foldervalues.Count();
fileName = fileName.Replace('\\', '_').Replace('/', '_').Replace(':', '_').Replace('!', '_').Replace('\'', '_').Replace('*', '_').Replace('#', '_').Replace('[', '_').Replace(']', '_');
var request = CreateService.BuildService(user).Files.Export(fileId, mimetype);
//Default extensions for files. Not sure what this should be, so we'll null it for now.
string ext = null;
// Things get sloppy here. The reason we're checking MimeTypes
// is because we have to export the files from Google's format
// to a format that is readable by a desktop computer program
// So for example, the google-apps.spreadsheet will become an MS Excel file.
if (mimetype == mimeSheet || mimetype == mimeSheetRitz || mimetype == mimeSheetml)
{
request = CreateService.BuildService(user).Files.Export(fileId, exportSheet);
ext = ".xls";
}
if (mimetype == mimeDoc || mimetype == mimeDocKix || mimetype == mimeDocWord)
{
request = CreateService.BuildService(user).Files.Export(fileId, exportDoc);
ext = ".docx";
}
if (mimetype == mimePres || mimetype == mimePresPunch)
{
request = CreateService.BuildService(user).Files.Export(fileId, exportPres);
ext = ".ppt";
}
if (mimetype == mimeForm || mimetype == mimeFormfb || mimetype == mimeFormDrawing)
{
request = CreateService.BuildService(user).Files.Export(fileId, exportForm);
ext = ".docx";
}
// Any other file type, assume as know what it is (which in our case, will be a txt file)
// apply the mime type and carry on.
string dest = Path.Combine(savelocation, fileName + ext);
var stream = new System.IO.FileStream(dest, FileMode.Create, FileAccess.ReadWrite);
int oops = 0;
// Add a handler which will be notified on progress changes.
// It will notify on each chunk download and when the
// download is completed or failed.
request.MediaDownloader.ProgressChanged +=
(IDownloadProgress progress) =>
{
switch (progress.Status)
{
case DownloadStatus.Downloading:
{
throw new Exception("File may be corrupted.");
break;
}
case DownloadStatus.Completed:
{
Console.WriteLine("Download complete.");
break;
}
case DownloadStatus.Failed:
{
oops = 1;
logFile.WriteLine(fileName + " could not be downloaded. Possible Google draw/form OR bad name.\n");
break;
}
}
};
request.Download(stream);
stream.Close();
stream.Dispose();
有什么方法可以简化这个过程,所以每次我想下载文件时都不需要构建驱动器服务吗?程序读取的平面文本文件看起来类似于
FILEID,实际文件名,MIMETYPE
那么有什么方法可以让中间人切断并提供请求。下载方法没有经常提醒" foreach"语句将文件类型导出为文件系统可读文件? (好抱怨,对不起,我知道这听起来很多。)
任何指针都会很棒!!
答案 0 :(得分:0)
您可能想要尝试教程:Google Drive API with C# .net – Download。这是一个更简单的代码来下载文件。还有其他因素,如间歇性互联网连接,可能会影响下载文件的ETA。
代码示例:
/// Download a file
/// Documentation: https://developers.google.com/drive/v2/reference/files/get
///
/// a Valid authenticated DriveService
/// File resource of the file to download
/// location of where to save the file including the file name to save it as.
///
public static Boolean downloadFile(DriveService _service, File _fileResource, string _saveTo)
{
if (!String.IsNullOrEmpty(_fileResource.DownloadUrl))
{
try
{
var x = _service.HttpClient.GetByteArrayAsync(_fileResource.DownloadUrl );
byte[] arrBytes = x.Result;
System.IO.File.WriteAllBytes(_saveTo, arrBytes);
return true;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
return false;
}
}
else
{
// The file doesn't have any content stored on Drive.
return false;
}
}
使用
_service.HttpClient.GetByteArrayAsync
我们可以传递我们想要下载的文件的下载URL。下载文件后,只需将文件转发到磁盘即可。
希望这有帮助!
答案 1 :(得分:0)
这不是一个答案,就像它是一个解决方案一样,即便如此,它只是答案的一半(现在。)我把手套脱掉并且玩得很脏。
首先,我将我的nuget google api软件包更新到我的VS项目中的最新版本,然后转到https://github.com/google/google-api-dotnet-client
,分叉/克隆它,更改了Google.Apis.Drive.v3.cs文件(编译为google.apis.drive.v3.dll),以便mimetype不再是只读的(它可以执行;并设置;,默认情况下,只允许获取)。
因为我已经知道了mime类型,所以我现在可以强制将mime类型分配给请求并继续我的生活,而不是必须构建客户端服务,连接,只导出我的文件类型已经知道了。
它不漂亮,不应该怎么做,但这真的很困扰我!
回到Mr.Rebot,我再次感谢你的帮助和研究! : - )