使用锐盒下载文件
本文关键字:下载 文件 | 更新日期: 2023-09-27 18:34:17
所以我有一些代码可以递归创建目录并重复下载文件夹中的文件。
这是代码:
public class Program
{
static void UploadDownloadProgress(Object sender, FileDataTransferEventArgs e)
{
// print a dot
Console.WriteLine("Downloading");
Console.WriteLine(".");
// it's ok to go forward
e.Cancel = false;
}
public static void DownloadFolder(CloudStorage dropBoxStorage, ICloudDirectoryEntry remoteDir, string targetDir, string sourceDir)
{
foreach (ICloudFileSystemEntry fsentry in remoteDir)
{
var filepath = Path.Combine(targetDir, fsentry.Name);
if (fsentry is ICloudDirectoryEntry)
{
Console.WriteLine("Created: {0}", filepath);
Directory.CreateDirectory(filepath);
DownloadFolder(dropBoxStorage, fsentry as ICloudDirectoryEntry, filepath, sourceDir);
}
else
{
dropBoxStorage.DownloadFile(remoteDir, fsentry.Name, targetDir, UploadDownloadProgress);
}
}
}
static void Main(string[] args)
{
CloudStorage dropBoxStorage = new CloudStorage();
var dropBixConfig = CloudStorage.GetCloudConfigurationEasy(nSupportedCloudConfigurations.DropBox);
ICloudStorageAccessToken accessToken = null;
using (FileStream fs = File.Open(@"C:'Users'Michael'token.txt", FileMode.Open, FileAccess.Read, FileShare.None))
{
accessToken = dropBoxStorage.DeserializeSecurityToken(fs);
}
var storageToken = dropBoxStorage.Open(dropBixConfig, accessToken);
//do stuff
//var root = dropBoxStorage.GetRoot();
var publicFolder = dropBoxStorage.GetFolder("/Public");
foreach (var folder in publicFolder)
{
Boolean bIsDirectory = folder is ICloudDirectoryEntry;
Console.WriteLine("{0}: {1}", bIsDirectory ? "DIR" : "FIL", folder.Name);
}
string remoteDirName = @"/Public/IQSWS";
string targetDir = @"C:'Users'Michael'";
var remoteDir = dropBoxStorage.GetFolder(remoteDirName);
DownloadFolder(dropBoxStorage, remoteDir, targetDir, remoteDirName);
dropBoxStorage.Close();
}
public delegate void FileOperationProgressChanged(object sender, FileDataTransferEventArgs e);
}
循环在else
中找到第一个文件后,它会下载它,然后移动到下一个文件,但是它会在foreach
上抛出异常:
System.InvalidOperationException was unhandled
HResult=-2146233079
Message=Collection was modified; enumeration operation may not execute.
Source=mscorlib
StackTrace:
at System.Collections.Generic.Dictionary`2.ValueCollection.Enumerator.MoveNext()
at StartServer.Program.DownloadFolder(CloudStorage dropBoxStorage, ICloudDirectoryEntry remoteDir, String targetDir, String sourceDir) in c:'Users'Michael'Documents'Visual Studio 2012'Projects'IQS Source'StartServer'StartServer'Program.cs:line 29
at StartServer.Program.DownloadFolder(CloudStorage dropBoxStorage, ICloudDirectoryEntry remoteDir, String targetDir, String sourceDir) in c:'Users'Michael'Documents'Visual Studio 2012'Projects'IQS Source'StartServer'StartServer'Program.cs:line 39
at StartServer.Program.DownloadFolder(CloudStorage dropBoxStorage, ICloudDirectoryEntry remoteDir, String targetDir, String sourceDir) in c:'Users'Michael'Documents'Visual Studio 2012'Projects'IQS Source'StartServer'StartServer'Program.cs:line 39
at StartServer.Program.DownloadFolder(CloudStorage dropBoxStorage, ICloudDirectoryEntry remoteDir, String targetDir, String sourceDir) in c:'Users'Michael'Documents'Visual Studio 2012'Projects'IQS Source'StartServer'StartServer'Program.cs:line 39
at StartServer.Program.Main(String[] args) in c:'Users'Michael'Documents'Visual Studio 2012'Projects'IQS Source'StartServer'StartServer'Program.cs:line 80
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
为什么会这样?当我所做的只是下载文件时,为什么要编辑数组?
您将整个集合remoteDir
传递到 DownloadFile 方法中,该方法如下所示:
// AppLimit.CloudComputing.SharpBox.CloudStorage
public void DownloadFile(ICloudDirectoryEntry parent, string name, string targetPath, FileOperationProgressChanged delProgress)
{
if (parent == null || name == null || targetPath == null)
{
throw new SharpBoxException(SharpBoxErrorCodes.ErrorInvalidParameters);
}
targetPath = Environment.ExpandEnvironmentVariables(targetPath);
ICloudFileSystemEntry child = parent.GetChild(name);
using (FileStream fileStream = new FileStream(Path.Combine(targetPath, name), FileMode.Create, FileAccess.Write, FileShare.None))
{
child.GetDataTransferAccessor().Transfer(fileStream, nTransferDirection.nDownload, delProgress, null);
}
}
在此方法中可以修改parent
的唯一点似乎是它调用GetChild
的位置。看看GetChild(我用了IlSpy):
public ICloudFileSystemEntry GetChild(string name)
{
return this.GetChild(name, true);
}
public ICloudFileSystemEntry GetChild(string name, bool bThrowException)
{
this.RefreshResource();
ICloudFileSystemEntry cloudFileSystemEntry;
this._subDirectories.TryGetValue(name, out cloudFileSystemEntry);
if (cloudFileSystemEntry == null && bThrowException)
{
throw new SharpBoxException(SharpBoxErrorCodes.ErrorFileNotFound);
}
return cloudFileSystemEntry;
}
这反过来又要求RefreshResource
收藏。看起来像这样(假设了保管箱实现):
// AppLimit.CloudComputing.SharpBox.StorageProvider.BaseObjects.BaseDirectoryEntry
private void RefreshResource()
{
this._service.RefreshResource(this._session, this);
this._subDirectoriesRefreshedInitially = true;
}
// AppLimit.CloudComputing.SharpBox.StorageProvider.DropBox.Logic.DropBoxStorageProviderService
public override void RefreshResource(IStorageProviderSession session, ICloudFileSystemEntry resource)
{
string resourceUrlInternal = this.GetResourceUrlInternal(session, resource);
int num;
string text = DropBoxRequestParser.RequestResourceByUrl(resourceUrlInternal, this, session, out num);
if (text.Length == 0)
{
throw new SharpBoxException(SharpBoxErrorCodes.ErrorCouldNotRetrieveDirectoryList);
}
DropBoxRequestParser.UpdateObjectFromJsonString(text, resource as BaseFileEntry, this, session);
}
现在,这会调用UpdateObjectFromJsonString
(我不打算粘贴到这里,因为它很大),但这似乎更新了属于集合的resource
对象。因此,您的收藏会发生变化...和你的例外。
我建议你将源代码下载到SharpBox或使用IlSpy反汇编二进制文件,如果你对到底发生了什么感兴趣。但简而言之,如果您以这种方式下载文件,它将修改集合。
也许使用不会在整个集合中传递的其他DownloadFile
重载之一。
不确定问题是否已解决,但根据我的经验,集合修改需要您将 IEnumerable 对象投射到 ToList() 中,这样它就不会急切地加载。