[英]Asp.Net Azure Cloud - Getting files size takes long time
我想获得父文件夹下可用的各种子文件夹下所有文件的大小总和。
我得到了大小,但计算结果大约需要 15 秒。
这是代码:
var storageAccount = CloudStorageAccount.Parse("connectionString");
var fileClient = storageAccount.CreateCloudFileClient();
var cloudFileShare = fileClient.GetShareReference("shareName");
var rootDirectory = cloudFileShare.GetRootDirectoryReference();
var directory = rootDirectory.GetDirectoryReference("folderName");
var size = directory.ListFilesAndDirectories().Select(x => (CloudFileDirectory)x).SelectMany(x => x.ListFilesAndDirectories()).Sum(x => ((CloudFile)x).Properties.Length);
我可以进一步优化它以快速获得尺寸吗?
编辑1:
测试:
发现:
检查您的 LINQ 查询:
var size = directory
.ListFilesAndDirectories()
.Select(x => (CloudFileDirectory)x)
.SelectMany(x => x.ListFilesAndDirectories())
.Sum(x => ((CloudFile)x).Properties.Length);
我可以看到一些初始问题。 首先,这假设根目录中的第一级仅存在目录。 这可以通过转换(CloudFileDirectory)x
看到。 如果找到CloudFile
这将引发异常。 可扩展的解决方案应该处理这两种类型的文件。 其次,这个查询还假设每个子目录中只存在文件,因此(CloudFile)x
转换。 这意味着这只会在子目录中深入一层,并且不会遍历任何子目录。 如果找到任何子目录,这也会引发异常。 我在下面概述了一些更具可扩展性的方法。
解决方案1:
使用CloudFileDirectory.ListFilesAndDirectories()
,它将所有文件组合成一个IEnumerable<IListFileItem>
。 如果找到文件,则递归遍历每个项目并总结找到的 btyes,如果找到目录,则递归。
public static void FileShareByteCount(CloudFileDirectory directory, ref long bytesCount)
{
if (directory == null)
{
throw new ArgumentNullException("directory", "Directory cannot be null");
}
var files = directory.ListFilesAndDirectories();
foreach (var item in files)
{
if (item.GetType() == typeof(CloudFileDirectory))
{
var cloudFileDirectory = item as CloudFileDirectory;
FileShareByteCount(cloudFileDirectory, ref bytesCount);
}
else if (item.GetType() == typeof(CloudFile))
{
var cloudFile = item as CloudFile;
bytesCount += cloudFile.Properties.Length;
}
}
}
用法一:
long bytesCount = 0;
FileShareByteCount(sampleDir, ref bytesCount);
Console.WriteLine($"Current file share usage: {bytesCount}");
解决方案2:
使用CloudFileDirectory.ListFilesAndDirectoriesSegmented()
分批浏览文件共享,它允许您指定每个IEnumerable<IListFileItem>
段要返回的文件数。 同上,递归遍历每一项并在找到文件时总结找到的字节数,如果找到目录则递归。
public static void FileShareByteCount(CloudFileDirectory directory, int? maxResults, ref long bytesCount)
{
if (directory == null)
{
throw new ArgumentNullException("directory", "Directory cannot be null");
}
FileContinuationToken continuationToken = null;
do
{
var resultSegment = directory.ListFilesAndDirectoriesSegmented(maxResults, continuationToken, null, null);
var results = resultSegment.Results;
if (results.Count() > 0)
{
foreach (var item in results)
{
if (item.GetType() == typeof(CloudFileDirectory))
{
var cloudFileDirectory = item as CloudFileDirectory;
FileShareByteCount(cloudFileDirectory, maxResults, ref bytesCount);
}
else if (item.GetType() == typeof(CloudFile))
{
var cloudFile = item as CloudFile;
bytesCount += cloudFile.Properties.Length;
}
}
}
continuationToken = resultSegment.ContinuationToken;
} while (continuationToken != null);
}
用法2:
long bytesCount = 0;
FileShareByteCount(directory, 100, ref bytesCount);
Console.WriteLine($"Current file share usage: {bytesCount}");
注意:您可以使用maxResults
指定段的最大大小。 Microsoft 文档指出:
一个非负整数值,表示一次返回的最大结果数,最多为每次操作限制 5000。如果此值为空,则将返回最大可能的结果数,最多为 5000。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.